diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b5be221 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Docker +!.gitkeep + +# macOS +*.DS_Store +.AppleDouble +.LSOverride +._* + +# Linux +*~ + +# Windows +Desktop.ini +Thumbs.db + diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..ce46a05 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,26 @@ +[author]: # (Frederico Martins ) +[version]: # (1.0) +[license]: # (SPDX-License-Identifier: CC-BY-4.0) +[copyright]: # (2016-2019, Frederico Martins) + +This project follows a No Code of Conduct (NCoC) philosophy. We are all human +beings. We should all be capable of getting along well. + +# Contributor (No) Code of Conduct + +Everyone is expected to behave like an adult and therefore be capable of +having adult discussions. Everyone contributions are accepted regardless of +their level of experience, gender, gender identity and expression, sexual +orientation, disability, personal appearance, body size, race, ethnicity, age, +religion, or nationality. The owners or copyright holders of this project are +not members of a support group for human emotion. This is a community that +strives to focus around its topics. Anything else takes away from that. + +Everyone should be able to freely express their ideas without being offended +by nor offend others. + +PROBLEMS, OR OTHER SITUATIONS, SHOULD BE ADDRESSED LIKE IN ANY OTHER PLATFORM, +PROJECT OR DISCUSSION FORUM. IN NO EVENT SHALL THE OWNERS OR COPYRIGHT HOLDERS +OF THIS PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +THIS PROJECT COMMUNITY. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..3903a69 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,37 @@ +# Contributing + +If you are thinking of contributing code to this project, first of all, thank +you! All fixes, patches and enhancements to it are very warmly welcomed. + +Please take a moment to review this document in order to find how your +contribution can be possible. + +## Bugs and Feature Requests + +The preferred way to report bugs or request features is to use +[GitHub issues](issues). For this project, however, that feature is not +available. + +## Pull Requests + +1. Create a [GitHub account](https://github.com/join) (if you don't have one already) +2. [Fork](https://help.github.com/articles/fork-a-repo) this project +3. Create your feature branch: `git checkout -b my-new-feature` +4. Make your changes +5. Commit your changes: `git commit -am 'Add some feature'` +6. Push to the branch: `git push origin my-new-feature` +7. Submit a pull request + +Before you submit a +[pull request](https://help.github.com/articles/using-pull-requests/) from your +forked repo, check that it meets these guidelines: + +- If the pull request adds or changes a functionality, make sure the +documentation is also created or updated as part of the same pull request. +- Try not to put more than one feature or bug fix in a single pull request. Create a +separate pull request for each feature or bug fix. +- Squash your commits into one for each pull request: `git reset --soft HEAD~ && git commit`. + +## License + +By contributing to this project, you agree that your contributions will be licensed under its [LICENSE](LICENSE). diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a0a35ab --- /dev/null +++ b/Dockerfile @@ -0,0 +1,112 @@ +FROM fscm/debian:stretch as build + +ARG BUSYBOX_VERSION="1.30.0" +ARG GOLANG_VERSION="1.11.5" +ARG PYTHON_VERSION="2.7.15" +ARG PRITUNL_VERSION="1.29.1979.98" + +ENV DEBIAN_FRONTEND=noninteractive + +COPY files/* /usr/local/bin/ + +RUN \ + apt-get -qq update && \ + apt-get -qq -y -o=Dpkg::Use-Pty=0 --no-install-recommends install \ + autoconf autotools-dev bzip2 curl g++ gcc git make tar \ + blt-dev tcl-dev tk-dev zlib1g-dev \ + ca-certificates iptables net-tools openssl openvpn \ + libbluetooth-dev libbz2-dev libc-dev libdb-dev libexpat1-dev libffi-dev \ + libgdbm-dev libgpm2 liblzma-dev libncursesw5-dev libreadline-dev \ + libsqlite3-dev libssl-dev libtinfo-dev \ + lsb-release \ + sharutils && \ + sed -i '/path-include/d' /etc/dpkg/dpkg.cfg.d/90docker-excludes && \ + mkdir -p /build/data/pritunl && \ + mkdir -p /src/apt/dpkg && \ + chmod -R o+rw /src/apt && \ + cp -r /var/lib/dpkg/* /src/apt/dpkg/ && \ + cd /src/apt && \ + apt-get -qq -y -o=Dpkg::Use-Pty=0 download bash ca-certificates iptables net-tools openssl openvpn && \ + dpkg --unpack --force-all --no-triggers --instdir=/build --admindir=/src/apt/dpkg --path-exclude="/usr/share*" openssl_*.deb && \ + dpkg --unpack --force-all --no-triggers --instdir=/build --admindir=/src/apt/dpkg --path-exclude="/usr/share*" iptables_*.deb && \ + dpkg --unpack --force-all --no-triggers --instdir=/build --admindir=/src/apt/dpkg --path-exclude="/etc*" --path-exclude="/usr/share*" bash_*.deb && \ + dpkg --unpack --force-all --no-triggers --instdir=/build --admindir=/src/apt/dpkg --path-exclude="/usr/*" --path-include="/usr/sbin*" net-tools_*.deb && \ + dpkg --unpack --force-all --no-triggers --instdir=/build --admindir=/src/apt/dpkg --path-exclude="/etc*" --path-exclude="/lib*" --path-exclude="/usr/*" --path-include="/usr/lib*" --path-include="/usr/sbin*" openvpn_*.deb && \ + dpkg --unpack --force-all --no-triggers --instdir=/build --admindir=/src/apt/dpkg --path-exclude="/etc*" --path-exclude="/usr/sbin*" --path-exclude="/usr/share/*" --path-include="/usr/share/ca-certificates*" ca-certificates_*.deb && \ + ln -s /bin/bash /build/bin/sh && \ + for f in `find /build -name '*.dpkg-new'`; do mv "${f}" "${f%.dpkg-new}"; done && \ + update-ca-certificates --etccertsdir /build/etc/ssl/certs/ && \ + cd - && \ + mkdir -p /src/python && \ + curl -sL --retry 3 --insecure "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-${PYTHON_VERSION}.tgz" | tar xz --no-same-owner --strip-components=1 -C /src/python/ && \ + cd /src/python && \ + rm -rf Modules/expat && \ + rm -rf Modules/zlib && \ + for d in darwin libffi libffi_arm_wince libffi_msvc libffi_osx; do rm -r Modules/_ctypes/${d}; done && \ + for f in md5module.c md5.c shamodule.c sha256module.c sha512module.c; do rm Modules/${f}; done && \ + CFLAGS="-Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security" LDFLAGS="-Wl,-z,relro" ./configure \ + --build="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" \ + --quiet \ + --prefix="" \ + --enable-ipv6 \ + --enable-shared \ + --enable-unicode=ucs4 \ + --with-computed-gotos \ + --with-dbmliborder=bdb:gdbm \ + --with-fpectl \ + --with-system-expat \ + --with-system-ffi \ + --with-ensurepip=install && \ + make --silent && \ + make --silent install DESTDIR=/build && \ + ln -s /build/bin/python2.7 /bin/python2.7 && \ + cd - && \ + mkdir -p /opt/golang && \ + curl -sL --retry 3 --insecure "https://dl.google.com/go/go${GOLANG_VERSION}.linux-amd64.tar.gz" | tar xz --no-same-owner --strip-components=0 -C /opt/golang/ && \ + PATH=$PATH:/opt/golang/go/bin GOPATH=/opt/golang GOBIN=/build/bin go get -u github.com/pritunl/pritunl-dns && \ + PATH=$PATH:/opt/golang/go/bin GOPATH=/opt/golang GOBIN=/build/bin go get -u github.com/pritunl/pritunl-web && \ + mkdir /src/pritunl && \ + curl -sL --retry 3 --insecure "https://github.com/pritunl/pritunl/archive/${PRITUNL_VERSION}.tar.gz" | tar xz --no-same-owner --strip-components=1 -C /src/pritunl/ && \ + cd /src/pritunl && \ + for f in $(grep -Rl 'var/lib/pritunl' /src/pritunl/*); do sed -i 's,var/lib/pritunl,data/pritunl,g' ${f}; done && \ + PATH=$PATH:/build/bin LD_LIBRARY_PATH=/build/lib /bin/python2.7 -E setup.py --quiet build --no-systemd && \ + PATH=$PATH:/build/bin LD_LIBRARY_PATH=/build/lib CFLAGS=-I/build/include CPPFLAGS=-I/build/include LDFLAGS=-L/build/lib pip install --quiet --requirement requirements.txt && \ + PATH=$PATH:/build/bin LD_LIBRARY_PATH=/build/lib /bin/python2.7 -E setup.py --quiet install --no-systemd --root /build/ --prefix "" && \ + mv /build/etc/pritunl.conf /build/etc/pritunl.conf.orig && \ + ln -s /data/pritunl/pritunl.conf /build/etc/pritunl.conf && \ + cd - && \ + rm -rf /build/include /build/share /build/build && \ + find /build/ -depth \( \( -type d -a \( -name test -o -name tests \) \) -o \( -type f -a \( -name '*.pyc' -o -name '*.pyo' \) \) \) -exec rm -rf '{}' + && \ + mkdir -p /build/run/systemd && \ + echo 'docker' > /build/run/systemd/container && \ + curl -sL --retry 3 --insecure "https://raw.githubusercontent.com/fscm/tools/master/lddcp/lddcp" -o ./lddcp && \ + chmod +x ./lddcp && \ + ./lddcp $(for f in `find /build/ -type f -executable`; do echo "-p $f "; done) $(for f in `find /lib/x86_64-linux-gnu/ \( -name 'libnss*' -o -name 'libresolv*' \)`; do echo "-l $f "; done) -d /build && \ + curl -sL --retry 3 --insecure "https://busybox.net/downloads/binaries/${BUSYBOX_VERSION}-i686/busybox" -o /build/bin/busybox && \ + chmod +x /build/bin/busybox && \ + for p in [ [[ basename cat cp date diff du echo env free grep ip killall less ln ls mkdir mknod mktemp more mv ping ps rm sed sort stty sysctl tr; do ln -s busybox /build/bin/${p}; done && \ + ln -s /bin/ip /build/sbin/ip && \ + chmod a+x /usr/local/bin/* && \ + cp /usr/local/bin/* /build/bin/ + + + +FROM scratch + +LABEL \ + maintainer="Frederico Martins " + +EXPOSE \ + 80 \ + 443 \ + 1194 \ + 1194/udp + +COPY --from=build \ + /build . + +VOLUME ["/data/pritunl"] + +ENTRYPOINT ["/bin/run"] + +CMD ["help"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8b42244 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016-2019, Frederico Martins + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cc1d025 --- /dev/null +++ b/README.md @@ -0,0 +1,220 @@ +# Pritunl for Docker + +Docker image that should be used to start an Pritunl server. + +## Synopsis + +This script will create a Docker image with Pritunl installed and with all +of the required initialisation scripts. + +The Docker image resulting from this script should be the one used to +instantiate a Pritunl server. + +## Getting Started + +There are a couple of things needed for the script to work. + +### Prerequisites + +Docker, either the Community Edition (CE) or Enterprise Edition (EE), needs to +be installed on your local computer. + +#### Docker + +Docker installation instructions can be found +[here](https://docs.docker.com/install/). + +### Usage + +In order to create a Docker image using this Dockerfile you need to run the +`docker` command with a few options. + +``` +docker build --squash --force-rm --no-cache --quiet --tag /: +``` + +* `` - *[required]* The user that will own the container image (e.g.: "johndoe"). +* `` - *[required]* The container name (e.g.: "pritunl"). +* `` - *[required]* The container tag (e.g.: "latest"). +* `` - *[required]* The location of the Dockerfile folder. + +A build example: + +``` +docker build --squash --force-rm --no-cache --quiet --tag johndoe/my_pritunl:latest . +``` + +To clean the __ image left by the `--squash` option the following command +can be used: + +``` +docker rmi `docker images --filter "dangling=true" --quiet` +``` + +### Instantiate a Container + +In order to end up with a functional Pritunl service - after having build +the container - some configurations have to be performed. + +To help perform those configurations a small set of commands is included on the +Docker container. + +- `help` - Usage help. +- `init` - Configure the Pritunl service. +- `start` - Start the Pritunl service. + +To store the configuration settings of the Pritunl server as well as the users +A couple of volumes should be created and added the the container when running +the same. + +#### Creating Volumes + +To be able to make all of the Pritunl data persistent, the same will have to +be stored on a different volume. + +Creating volumes can be done using the `docker` tool. To create a volume use +the following command: + +``` +docker volume create --name +``` + +Two create the two required volumes the following set of commands can be used: + +``` +docker volume create --name my_pritunl +``` + +#### Configuring the Pritunl Server + +To configure the Pritunl server the `init` command must be used. + +``` +docker run --volume :/data/pritunl:rw --rm /: [options] init +``` + +* `-m ` - *[required]* The MongoDB URI (e.g.: mongodb://mongodb.host:27017/pritunl). + +After this step the Pritunl server should be configured and ready to use. + +An example on how to configure the Pritunl server: + +``` +docker run --volume my_pritunl:/data/pritunl:rw --rm johndoe/my_pritunl:latest -m mongodb://mongodb:27017/pritunl init +``` + +#### Start the Pritunl Server + +After configuring the Pritunl server the same can now be started. + +Starting the Pritunl server can be done with the `start` command. + +``` +docker run --volume :/data/pritunl:rw --detach --interactive --tty -p 1194:1194/udp -p 1194:1194 -p 443:443 -p 80:80 --privileged --cap-add=NET_ADMIN --device=/dev/net/tun /: start +``` + +The Docker options `--cap-add=NET_ADMIN`, `--device=/dev/net/tun`, and +`--privileged` are required for the container to be able to start. + +To help managing the container and the Pritunl instance a name can be given to +the container. To do this use the `--name ` docker option when starting +the server + +An example on how the Pritunl service can be started: + +``` +docker run --volume my_pritunl:/data/pritunl:rw --detach --interactive --tty -p 1194:1194/udp -p 1194:1194 -p 443:443 -p 80:80 --privileged --cap-add=NET_ADMIN --device=/dev/net/tun --name my_pritunl johndoe/my_pritunl:latest start +``` + +To see the output of the container that was started use the following command: + +``` +docker attach +``` + +Use the `ctrl+p` `ctrl+q` command sequence to detach from the container. + +#### Stop the Pritunl Server + +If needed the Pritunl server can be stoped and later started again (as long as +the command used to perform the initial start was as indicated before). + +To stop the server use the following command: + +``` +docker stop +``` + +To start the server again use the following command: + +``` +docker start +``` + +### Pritunl Status + +The Pritunl server status can be check by looking at the Unbound server output +data using the docker command: + +``` +docker container logs +``` + +### Add Tags to the Docker Image + +Additional tags can be added to the image using the following command: + +``` +docker tag /: +``` + +### Push the image to Docker Hub + +After adding an image to Docker, that image can be pushed to a Docker +registry... Like Docker Hub. + +Make sure that you are logged in to the service. + +``` +docker login +``` + +When logged in, an image can be pushed using the following command: + +``` +docker push /: +``` + +Extra tags can also be pushed. + +``` +docker push /: +``` + +## Contributing + +1. Fork it! +2. Create your feature branch: `git checkout -b my-new-feature` +3. Commit your changes: `git commit -am 'Add some feature'` +4. Push to the branch: `git push origin my-new-feature` +5. Submit a pull request + +Please read the [CONTRIBUTING.md](CONTRIBUTING.md) file for more details on how +to contribute to this project. + +## Versioning + +This project uses [SemVer](http://semver.org/) for versioning. For the versions +available, see the [tags on this repository](https://github.com/fscm/docker-pritunl/tags). + +## Authors + +* **Frederico Martins** - [fscm](https://github.com/fscm) + +See also the list of [contributors](https://github.com/fscm/docker-pritunl/contributors) +who participated in this project. + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) +file for details diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d8c4d19 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,39 @@ +version: '3.4' + +volumes: + mongodb_data: + driver: local + name: my_mongodb + pritunl_data: + driver: local + name: my_pritunl + +services: + mongodb: + container_name: my_mongodb + image: "fscm/mongodb:latest" + volumes: + - "mongodb_data:/data/mongodb" + ports: + - "27017:27017" + command: ["start"] + pritunl: + container_name: my_pritunl + privileged: true + image: "fscm/pritunl:latest" + volumes: + - "pritunl_data:/data/pritunl" + ports: + - '80:80' + - '443:443' + - '1194:1194/udp' + - '1194:1194/tcp' + cap_add: + - NET_ADMIN + devices: + - "/dev/net/tun:/dev/net/tun" + depends_on: + - "mongodb" + links: + - "mongodb" + command: ["-m", "mongodb://mongodb:27017/pritunl", "init", "start"] diff --git a/files/run b/files/run new file mode 100755 index 0000000..ddb4b94 --- /dev/null +++ b/files/run @@ -0,0 +1,192 @@ +#!/bin/bash +# +# Shell script to start the Pritunl Docker image. +# +# Copyright 2016-2019, Frederico Martins +# Author: Frederico Martins +# +# SPDX-License-Identifier: MIT +# +# This program is free software. You can use it and/or modify it under the +# terms of the MIT License. +# + +set -e + +BASENAME=$(basename "${0}") +__TS__=$(date +%Y%m%d%H%M%S) + + +# Variables +ACTION_HELP=0 +ACTION_INIT=0 +ACTION_START=0 + +MONGODB_URI= +MONGODB_URI_DB= +MONGODB_URI_PORT= +MONGODB_URI_PROTO= +MONGODB_URI_ADDRESS= +MONGODB_URI_OPTIONS= +MONGODB_URI_CREDENTIALS= + +__PRITUNL_DATA__="/data/pritunl" + + +# Configuration files +PRITUNL_CONF="${__PRITUNL_DATA__}/pritunl.conf" + + +# Usage +function show_usage() { + echo "Usage: ${BASENAME} [options] (help|init|start)" + echo " help:" + echo " " + echo " init:" + echo " -m The MongoDB URI (e.g.: mongodb://mongodb.host:27017/pritunl)" + echo " start:" + echo " " +} + + +# Options parsing +while getopts ":m:" opt; do + case ${opt} in + m) + MONGODB_URI=${OPTARG} + ;; + \?) + echo >&2 " [ERROR] Invalid option: -${OPTARG}" + exit 1 + ;; + :) + echo >&2 " [ERROR] Option -${OPTARG} requires an argument" + exit 2 + ;; + esac +done + +shift $((OPTIND-1)) + +for command in "${@}"; do + case "${command,,}" in + help) + ACTION_HELP=1 + ;; + init) + ACTION_INIT=1 + ;; + start) + ACTION_START=1 + ;; + *) + echo >&2 " [WARN] Unknown command '${command}'" + ;; + esac +done + + +# Check arguments +if [[ $# -eq 0 ]]; then + show_usage + exit 3 +fi +if ! ((ACTION_HELP+ACTION_INIT+ACTION_START)); then + show_usage + exit 0 +fi + + +# Check permissions +if [[ $EUID -ne 0 ]]; then + echo >&2 " [ERROR] This script requires privileged access to system files" + exit 4 +fi + + +# === HELP === +if [[ "${ACTION_HELP}" -gt 0 ]]; then + show_usage + exit 0 +fi + + +# === INIT === +if [[ "${ACTION_INIT}" -gt 0 ]]; then + + # Check requirements + if [[ "x${MONGODB_URI}" = "x" ]]; then + echo >&2 " [ERROR] The MongoDB URI (-m) option is mandatory." + exit 5 + fi + + # Backup configuration files or copy if it does not exist yet + if [[ -f ${PRITUNL_CONF} ]]; then + cp "${PRITUNL_CONF}" "${PRITUNL_CONF}.${__TS__}.bck" + else + cp "/etc/pritunl.conf.orig" "${PRITUNL_CONF}" + fi + + # set Pritunl MongoDB URI + #if ! [[ "x${MONGODB_URI}" = "x" ]]; then + if [[ "${MONGODB_URI}" =~ ^((mongodb)://)?(([0-9a-zA-Z]+:[0-9a-zA-Z]+)@)?([0-9a-zA-Z\.\-]+)(:([0-9]+))?/([0-9a-zA-Z\.\-]+)(\?[=\&0-9a-zA-Z]+)?$ ]]; then + MONGODB_URI_PROTO=${BASH_REMATCH[2]:-mongodb} + MONGODB_URI_CREDENTIALS=${BASH_REMATCH[3]} + MONGODB_URI_ADDRESS=${BASH_REMATCH[5]} + MONGODB_URI_PORT=${BASH_REMATCH[7]:-27017} + MONGODB_URI_DB=${BASH_REMATCH[8]} + MONGODB_URI_OPTIONS=${BASH_REMATCH[9]} + else + echo >&2 " [ERROR] Invalid MongoDB URI." + exit 6 + fi + /bin/pritunl set-mongodb "${MONGODB_URI_PROTO}://${MONGODB_URI_CREDENTIALS}${MONGODB_URI_ADDRESS}:${MONGODB_URI_PORT}/${MONGODB_URI_DB}${MONGODB_URI_OPTIONS}" + #sed -i "/mongodb_uri/s|: .*$|: \"${MONGODB_URI_PROTO}://${MONGODB_URI_CREDENTIALS}${MONGODB_URI_ADDRESS}:${MONGODB_URI_PORT}/${MONGODB_URI_DB}${MONGODB_URI_OPTIONS}\"|" "${PRITUNL_CONF}" + #fi + + # Get setup-key + echo -e "==================================\nSetupKey:\n `/bin/pritunl setup-key 2>/dev/null` \n==================================" + + # Get default credentials + echo -e "==================================\n `/bin/pritunl default-password` \n==================================" + + # Clean up unneeded backups + diff -q "${PRITUNL_CONF}" "${PRITUNL_CONF}.${__TS__}.bck" &> /dev/null && rm -f "${PRITUNL_CONF}.${__TS__}.bck" || true + + # All done + echo " [INFO] Configuration(s) successfully updated" +fi + + +# === START === +if [[ "${ACTION_START}" -gt 0 ]]; then + + # Create temporary dir (if needed) + if ! [[ -d /tmp ]]; then + mkdir -p -m 1777 /tmp + fi + + # Create run dir (if needed) + if ! [[ -d /var/run ]]; then + mkdir -p -m 0755 /var/run + fi + + # Create required device(s) + if ! [[ -d /dev/net ]]; then + mkdir -p -m 755 /dev/net + fi + if ! [[ -c /dev/net/tun ]]; then + mknod /dev/net/tun c 10 200 + fi + + # Start the Pritunl server + if [[ -f "${PRITUNL_CONF}" ]]; then + /bin/pritunl start --conf ${PRITUNL_CONF} + else + echo >&2 " [ERROR] Pritunl configuration not found." + exit 7 + fi +fi + +# All done +exit 0