From 92388f1ab58e333812d47efed8ba04a2294252ed Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 27 Jul 2019 13:17:52 +0200 Subject: [PATCH 01/14] Added exec permission to sbin scripts --- root/usr/local/sbin/ovpn-ip | 0 root/usr/local/sbin/ovpn-ip6tables | 0 root/usr/local/sbin/ovpn-iptables | 0 root/usr/local/sbin/ovpn-route | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 root/usr/local/sbin/ovpn-ip mode change 100644 => 100755 root/usr/local/sbin/ovpn-ip6tables mode change 100644 => 100755 root/usr/local/sbin/ovpn-iptables mode change 100644 => 100755 root/usr/local/sbin/ovpn-route diff --git a/root/usr/local/sbin/ovpn-ip b/root/usr/local/sbin/ovpn-ip old mode 100644 new mode 100755 diff --git a/root/usr/local/sbin/ovpn-ip6tables b/root/usr/local/sbin/ovpn-ip6tables old mode 100644 new mode 100755 diff --git a/root/usr/local/sbin/ovpn-iptables b/root/usr/local/sbin/ovpn-iptables old mode 100644 new mode 100755 diff --git a/root/usr/local/sbin/ovpn-route b/root/usr/local/sbin/ovpn-route old mode 100644 new mode 100755 From d6eb2875c9388bed8144f3e518d850b9a5877056 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 00:22:13 +0200 Subject: [PATCH 02/14] Partial rewrite Changed config directory structure, changed command names, added backup/restore, reorganized code, switched to new baseimage --- CHANGELOG.md | 11 + CONTRIBUTING.md | 104 +++++----- Dockerfile | 83 ++++---- README.md | 20 +- docs/Commands.md | 101 ++++++++++ docs/README.md | 85 +------- docs/SetupGuide.md | 14 +- hooks/build | 10 +- root/app/bin/ovpn_backup | 44 ---- root/app/bin/ovpn_client | 120 ----------- root/app/bin/ovpn_disconf | 40 ---- root/app/bin/ovpn_enconf | 189 ------------------ root/app/bin/ovpn_findopt | 28 --- root/app/bin/ovpn_init | 73 ------- root/app/bin/run_hooks | 63 ------ root/app/hookBaseFirewall.sh | 20 ++ root/app/lib/settings | 42 ---- root/app/lib/utils | 60 ------ root/app/{lib => }/libovpn.py | 0 root/defaults/example/README.md | 58 +++--- .../example/config/basic_nat/README.md | 2 +- .../config/basic_nat/client/client.conf | 1 - .../basic_nat/{server => config}/server.conf | 0 .../config/basic_nat/hooks/down/10-network.sh | 17 +- .../basic_nat/hooks/finish/10-network.sh | 18 +- .../config/basic_nat/hooks/init/10-network.sh | 18 +- .../config/basic_nat/hooks/up/10-network.sh | 17 +- root/defaults/example/config/basic_nat/wizard | 38 ++-- .../example/config/basic_nat_wlp/README.md | 2 +- .../config/basic_nat_wlp/client/client.conf | 1 - .../{server => config}/server.conf | 0 .../basic_nat_wlp/hooks/down/10-network.sh | 17 +- .../basic_nat_wlp/hooks/finish/10-network.sh | 16 +- .../basic_nat_wlp/hooks/init/10-network.sh | 16 +- .../basic_nat_wlp/hooks/up/10-network.sh | 17 +- .../example/config/basic_nat_wlp/wizard | 54 ++--- .../example/config/basic_routed/README.md | 2 +- .../config/basic_routed/client/client.conf | 1 - .../{server => config}/server.conf | 0 .../basic_routed/hooks/down/10-network.sh | 17 +- .../basic_routed/hooks/finish/10-network.sh | 18 +- .../basic_routed/hooks/init/10-network.sh | 18 +- .../basic_routed/hooks/up/10-network.sh | 17 +- .../example/config/basic_routed/wizard | 54 ++--- root/defaults/{ => openvpn}/system.conf | 28 +-- root/etc/cont-finish.d/60-network | 17 -- root/etc/cont-finish.d/60-network.sh | 11 + .../{99-custom_finish => 99-custom_finish.sh} | 0 root/etc/cont-init.d/20-env | 36 ---- root/etc/cont-init.d/50-config | 115 ----------- root/etc/cont-init.d/50-setup.sh | 83 ++++++++ root/etc/cont-init.d/60-network | 37 ---- root/etc/cont-init.d/60-network.sh | 31 +++ root/etc/cont-init.d/70-config.sh | 23 +++ .../{99-custom_init => 99-custom_init.sh} | 0 root/etc/logrotate.d/openvpn | 9 - root/etc/services.d/openvpn/finish | 9 + root/etc/services.d/openvpn/run | 30 ++- root/usr/local/bin/ovpn | 41 ++++ root/usr/local/bin/ovpn_backup | 15 ++ root/usr/local/bin/ovpn_client | 156 +++++++++++++++ root/usr/local/bin/ovpn_disconf | 40 ++++ root/usr/local/bin/ovpn_enconf | 109 ++++++++++ root/usr/local/bin/ovpn_pki | 86 ++++++++ root/usr/local/bin/ovpn_restore | 24 +++ root/usr/local/bin/run_hooks | 52 +++++ 66 files changed, 1087 insertions(+), 1391 deletions(-) create mode 100644 docs/Commands.md delete mode 100755 root/app/bin/ovpn_backup delete mode 100755 root/app/bin/ovpn_client delete mode 100755 root/app/bin/ovpn_disconf delete mode 100755 root/app/bin/ovpn_enconf delete mode 100644 root/app/bin/ovpn_findopt delete mode 100755 root/app/bin/ovpn_init delete mode 100755 root/app/bin/run_hooks create mode 100644 root/app/hookBaseFirewall.sh delete mode 100644 root/app/lib/settings delete mode 100644 root/app/lib/utils rename root/app/{lib => }/libovpn.py (100%) rename root/defaults/example/config/basic_nat/{server => config}/server.conf (100%) rename root/defaults/example/config/basic_nat_wlp/{server => config}/server.conf (100%) rename root/defaults/example/config/basic_routed/{server => config}/server.conf (100%) rename root/defaults/{ => openvpn}/system.conf (59%) delete mode 100755 root/etc/cont-finish.d/60-network create mode 100755 root/etc/cont-finish.d/60-network.sh rename root/etc/cont-finish.d/{99-custom_finish => 99-custom_finish.sh} (100%) delete mode 100644 root/etc/cont-init.d/20-env delete mode 100644 root/etc/cont-init.d/50-config create mode 100644 root/etc/cont-init.d/50-setup.sh delete mode 100644 root/etc/cont-init.d/60-network create mode 100644 root/etc/cont-init.d/60-network.sh create mode 100644 root/etc/cont-init.d/70-config.sh rename root/etc/cont-init.d/{99-custom_init => 99-custom_init.sh} (100%) delete mode 100644 root/etc/logrotate.d/openvpn create mode 100644 root/etc/services.d/openvpn/finish create mode 100755 root/usr/local/bin/ovpn create mode 100755 root/usr/local/bin/ovpn_backup create mode 100755 root/usr/local/bin/ovpn_client create mode 100755 root/usr/local/bin/ovpn_disconf create mode 100755 root/usr/local/bin/ovpn_enconf create mode 100755 root/usr/local/bin/ovpn_pki create mode 100644 root/usr/local/bin/ovpn_restore create mode 100755 root/usr/local/bin/run_hooks diff --git a/CHANGELOG.md b/CHANGELOG.md index 527535e..999f04d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +### 2.0.0 - Partial rewrite + +- Moved `/config/hooks` to `/config/openvpn/hooks` +- Renamed `/config/openvpn/server` to `config` +- Changed base image to [slocomptech/baseimage-alpine](https://github.com/SloCompTech/docker-baseimage-alpine) +- Moved all helper scripts to `/root/usr/local/bin` +- Got rid of bash lib files +- Hiearhicaly moved all commands under the hood of `ovpn` command +- Improved backup command +- Added restore command + ### 1.0.6 - Bugfix - Added missing `DNS` keyword to **dhcp-option** in example configs diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d065d30..2668afd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,76 +6,70 @@ Feel free to contribute to this project. Sections: -- [Example configs & hooks](root/defaults/example/README.md) +- [Example configs & hooks](root/defaults/example/README.md) - [Guides](docs/README.md) - [Helper Scripts](root/app/README.md) - [Modules](root/defaults/module/README.md) ## Syntax -- Identation: tab (4 spaces width) +- Identation: space (2 spaces width) - Javadoc style documentation ## Directory structure of project ``` -/app # Utils (part of image) - bin # Scripts for using this image /config # Configuration dir (all config is here, generated on container start) - openvpn # Openvpn configuration - ccd # Client config directory - client # Client configuration directory - .conf # Base for building client config (all files merged) - server # Server configuration directory - .conf # Server config files (all files merged) - pki - ca.crt # CA certificate - certs by serial # Certs by Serial ID - .pem - crl.pem # CRL - dh.pem - index.txt # Database index file - issued - .crt # Certificates - private # Directory with private keys - ca.key # CA secret - .key # Certificate secrets - reqs # Directroy with signing requests - serial # The current serial number - ta.key # Secret for tls-auth, tls-crypt - ssl - safessl-easyrsa.cnf - vars - example # Example configs (see root/defaults/example/README.md) - config # Example client & server configs - hook # Example hook configs - module # Modules for openvpn + backup # Folder where backups are generated + example # Example configs (see root/defaults/example/README.md) + module # Modules for openvpn + openvpn # Openvpn configuration + ccd # OpenVPN client-specific configuration directory (applied when client connects) + client # Client configuration directory (for generation of .ovpn files) + .conf # Base for building client config (all files merged) + config # Running config (server/client) + .conf # Config files (all files merged) hooks # Put your custom scripts in one of subfolders - auth # On authentication (needs to be enabled in config) - client-connect # Client connected - client-disconnect # Client disconnected - down # After interface is down - finish # Deinit container - init # Init container - learn-address - route-up # After routes are added - route-pre-down # Before routes are removed - up # After interface is up - tls-verify # Check certificate + auth # On authentication (needs to be enabled in config) + client-connect # Client connected + client-disconnect # Client disconnected + down # After interface is down + finish # Deinit container + init # Init container + learn-address + route-up # After routes are added + route-pre-down # Before routes are removed + up # After interface is up + tls-verify # Check certificate system.conf # System OpenVPN config file (do not edit, unless instructed) - include-server.conf # File that includes all server configuration files (automatically generated) - donotdelete # Leave this file alone, if deleted it triggers full setup + include-conf.conf # File that includes all configuration files (automatically generated) + pki + ca.crt # CA certificate + certs by serial # Certs by Serial ID + .pem + crl.pem # CRL + dh.pem + index.txt # Database index file + issued + .crt # Certificates + private # Directory with private keys + ca.key # CA secret + .key # Certificate secrets + reqs # Directroy with signing requests + secret.key # Static key (if not using real PKI) + serial # The current serial number + ta.key # Secret for tls-auth, tls-crypt + ssl + safessl-easyrsa.cnf + vars + tmp # Temporary folder /defaults # Default configuration, which is copied into config on full setup - example # Examples - config # Example configs - hook # Example hooks - module # Modules (for example password authentication ...) - system.conf # Original server config + ... /etc # System config - cont-init.d # Scripts run before services are started - fix-attrs.d # Fix file permissions - logrotate.d # Log settings - services.d # Scripts that start services + cont-init.d # Scripts run before services are started + cont-finish.d # Scripts run after services are finished + fix-attrs.d # Fix file permissions + services.d # Scripts that start services ``` ## Useful links @@ -92,4 +86,4 @@ Sections: - [OpenVPN docs](https://community.openvpn.net/openvpn/wiki/GettingStartedwithOVPN) - [Setup OpenVPN on alpine linux](https://wiki.alpinelinux.org/wiki/Setting_up_a_OpenVPN_server#Alternative_Certificate_Method) - [EasyRSA](https://community.openvpn.net/openvpn/wiki/GettingStartedwithOVPN) -- [EasyRSA doc](https://github.com/OpenVPN/easy-rsa/tree/master/doc) \ No newline at end of file +- [EasyRSA doc](https://github.com/OpenVPN/easy-rsa/tree/master/doc) diff --git a/Dockerfile b/Dockerfile index 6211e01..8ae86a0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # @see https://github.com/linuxserver/docker-baseimage-alpine # @see https://github.com/linuxserver/docker-baseimage-alpine-python3 # -FROM lsiobase/alpine.python3:latest +FROM slocomptech/baseimage-alpine # Build arguments ARG BUILD_DATE @@ -17,61 +17,76 @@ ARG VERSION # @see http://label-schema.org/rc1/ # @see https://semver.org/ # -LABEL org.opencontainers.image.title="OpenVPN Server" \ - org.label-schema.name="OpenVPN Server" \ - org.opencontainers.image.description="Docker image with OpenVPN server" \ - org.label-schema.description="Docker image with OpenVPN server" \ - org.opencontainers.image.url="https://github.com/SloCompTech/docker-openvpn" \ - org.label-schema.url="https://github.com/SloCompTech/docker-openvpn" \ - org.opencontainers.image.authors="Martin Dagarin " \ - org.opencontainers.image.version=$VERSION \ - org.label-schema.version=$VERSION \ - org.opencontainers.image.revision=$VCS_REF \ - org.label-schema.vcs-ref=$VCS_REF \ - org.opencontainers.image.source=$VCS_SRC \ - org.label-schema.vcs-url=$VCS_SRC \ - org.opencontainers.image.created=$BUILD_DATE \ - org.label-schema.build-date=$BUILD_DATE \ - org.label-schema.schema-version="1.0" +LABEL org.opencontainers.image.title="OpenVPN Server" \ + org.label-schema.name="OpenVPN Server" \ + org.opencontainers.image.description="Docker image with OpenVPN server" \ + org.label-schema.description="Docker image with OpenVPN server" \ + org.opencontainers.image.url="https://github.com/SloCompTech/docker-openvpn" \ + org.label-schema.url="https://github.com/SloCompTech/docker-openvpn" \ + org.opencontainers.image.authors="Martin Dagarin " \ + org.opencontainers.image.version=$VERSION \ + org.label-schema.version=$VERSION \ + org.opencontainers.image.revision=$VCS_REF \ + org.label-schema.vcs-ref=$VCS_REF \ + org.opencontainers.image.source=$VCS_SRC \ + org.label-schema.vcs-url=$VCS_SRC \ + org.opencontainers.image.created=$BUILD_DATE \ + org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.schema-version="1.0" # # Environment variables # @see https://github.com/OpenVPN/easy-rsa/blob/master/doc/EasyRSA-Advanced.md # -ENV PATH="/app/bin:$PATH" \ - S6_BEHAVIOUR_IF_STAGE2_FAILS=0 \ - EASYRSA=/usr/share/easy-rsa \ +ENV EASYRSA=/usr/share/easy-rsa \ EASYRSA_PKI=/config/pki \ EASYRSA_VARS_FILE=/config/ssl/vars \ #EASYRSA_SSL_CONF=/config/ssl/openssl-easyrsa.cnf \ EASYRSA_SAFE_CONF=/config/ssl/safessl-easyrsa.cnf \ - EASYRSA_TEMP_FILE=/config/temp \ - OVPN_ROOT=/config \ - OVPN_HOOKS=/config/hooks \ - OVPN_RUN=system.conf + EASYRSA_TEMP_FILE=/config/tmp/temp # Install packages -RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/main/" >> /etc/apk/repositories && \ - apk add --no-cache \ +RUN apk add --no-cache \ # Core packages - bash sudo iptables ip6tables git openvpn easy-rsa && \ + bash \ + easy-rsa \ + iptables \ + ip6tables \ + openvpn \ + python3 \ + sudo && \ # Link easy-rsa in bin directory ln -s ${EASYRSA}/easyrsa /usr/local/bin && \ # Link python3 also as python + ln -s /usr/bin/pip3 /usr/bin/pip && \ ln -s /usr/bin/python3 /usr/bin/python && \ # Remove any temporary files created by apk rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/* && \ # Add permission for network management to user abc - echo "abc ALL=(ALL) NOPASSWD: /sbin/ip, /sbin/ip6tables, /sbin/ip6tables-compat, /sbin/ip6tables-compat-restore, /sbin/ip6tables-compat-save, /sbin/ip6tables-restore, /sbin/ip6tables-restore-translate, \ - /sbin/ip6tables-save, /sbin/ip6tables-translate, /sbin/iptables, /sbin/iptables-compat, /sbin/iptables-compat-restore, /sbin/iptables-compat-save, \ - /sbin/iptables-restore, /sbin/iptables-restore-translate, /sbin/iptables-save, /sbin/iptables-translate, /sbin/route" \ - >> /etc/sudoers.d/abc + echo "abc ALL=(ALL) NOPASSWD: \ + /sbin/ip, \ + /sbin/ip6tables, \ + /sbin/ip6tables-compat, \ + /sbin/ip6tables-compat-restore, \ + /sbin/ip6tables-compat-save, \ + /sbin/ip6tables-restore, \ + /sbin/ip6tables-restore-translate, \ + /sbin/ip6tables-save, \ + /sbin/ip6tables-translate, \ + /sbin/iptables, \ + /sbin/iptables-compat, \ + /sbin/iptables-compat-restore, \ + /sbin/iptables-compat-save, \ + /sbin/iptables-restore, \ + /sbin/iptables-restore-translate, \ + /sbin/iptables-save, \ + /sbin/iptables-translate, \ + /sbin/route" \ + >> /etc/sudoers.d/abc # Add repo files to image COPY root/ / # Configure -RUN chmod +x /app/bin/* && \ - chmod +x /usr/local/sbin/* && \ - chmod -R 0644 /etc/logrotate.d +RUN chmod -R 0644 /etc/logrotate.d diff --git a/README.md b/README.md index e4b7cec..a23a05a 100644 --- a/README.md +++ b/README.md @@ -68,11 +68,13 @@ services: |**Parameter**|**Function**| |:-----------:|:----------:| +|`-e FAIL_MODE=hard`|Restart whole container on error| |`-e PUID=1000`|for UserID - see below for explanation| |`-e PGID=1000`|for GroupID - see below for explanation| -|`-e OVPN_NFW=true`|Disable any firewall related rules to be created, modified ... (must be implemented in example)| -|`-e OVPN_PERINT=true`|Enable persistent TUN interface| +|`-e PERSISTENT_INTERFACE=true`|Enable persistent TUN interface| +|`-e USE_FIREWALL=false`|Disable any firewall related rules to be created, modified ... (must be implemented in example)| |`-v /config`|All the config files including OpenVPNs reside here| +|`-v /log`|Log files reside here| See also: [EasyRSA](https://github.com/OpenVPN/easy-rsa/blob/master/doc/EasyRSA-Advanced.md) @@ -104,13 +106,13 @@ If you are new to containers please see rather [Detailed first setup guide](docs 2. At this point you will have bash shell which runs in container. Now run following commands to setup your PKI: ``` bash - ovpn_init [nopass] # Inits PKI + ovpn pki init [nopass] # Inits PKI ``` 3. Setup OpenVPN config based on example `basic_nat` with configuration wizard: ``` bash - ovpn_enconf basic_nat + ovpn enconf basic_nat #Out interface [eth0]: #Protocol udp, tcp, udp6, tcp6 [udp]: #VPN network [10.0.0.0]: @@ -125,13 +127,13 @@ If you are new to containers please see rather [Detailed first setup guide](docs ``` bash # Generates client certificates - ovpn_client add [nopass] + ovpn client add [nopass] - # Generates client config file and prints it to screen (redirect to file) - ovpn_client ovpn > .ovpn + # Generates client config file and saves it to /config/tmp + ovpn client ovpn # OR BETTER SOLLUTION: Run outside container - docker exec -it ovpn_client ovpn > .ovpn + docker exec -it ovpn client ovpnp > .ovpn ``` 5. Exit container with `exit`, then it will destroy itself. @@ -170,4 +172,4 @@ Wanted features (please help implement): ## Versions -See [CHANGELOG](CHANGELOG.md) \ No newline at end of file +See [CHANGELOG](CHANGELOG.md) diff --git a/docs/Commands.md b/docs/Commands.md new file mode 100644 index 0000000..bc76f44 --- /dev/null +++ b/docs/Commands.md @@ -0,0 +1,101 @@ +# Commands + +This chapter shows available commands. + +``` bash +$ ovpn help +Usage: ovpn COMMAND [ARGS..] + +Commands: + backup # Creates backup of configuration files + client [add|ovpn|ban|revoke|remove|delete|help] [NAME] [nopass] # Client manipulation + disconf # Deletes active config + enconf EXAMPLE_CONFIG_NAME [wizard args] # Enable example config + pki [init|remove|delete] # Public Key Intrastructure + restore ARCHIVE_FILE # Restores backup +``` + +## ovpn backup + +This command backups your configration into **.tar.gz** archive and puts it into `/config/backup` directory. + +### Usage + +``` bash +$ ovpn backup +``` + +**Note:** Store your backups in a **SECURE** way, because they are **unencrypted**. + +## ovpn client + +This commands manages clients of your OpenVPN server. + +``` bash +$ ovpn client help +Usage: ovpn_client COMMAND [ARGS] + +Commands: + add [NAME [nopass]] # Creates certificates for client + ovpn NAME # Generates .ovpn file (saves to tmp) + revoke|ban NAME # Adds client to CRL + remove|delete NAME # Removes client config +``` + +**Note:** First you need to use `add` to create client certificates, before you can use `ovpn` command. + +### Create .ovpn file for client + +``` bash +$ ovpn client add CLIENTNAME [nopass] +$ ovpn client ovpn CLIENTNAME +# .ovpn file is saved to /config/tmp +``` + +## ovpn disconf + +This command deletes your active configuration. **Container restart** is needed for changes to take affect. + +``` +$ ovpn disconf +``` + +**NOTE:** This command does not delete PKI. + +## ovpn enconf + +This command enables OpenVPN config based on config example. If config name isn't specified it prints out config list. + +``` +$ ovpn enconf help +Usage: ovpn_enconf CONFIG_NAME [wizard args...] + +Configs: + +``` + +**Note:** Please read example documentation to understand how to use it. +**Warning:** Some examples automaticaly add firewall rules, so if you are using host networking make sure to check **iptables** for correct configuration. +**Tip:** If you modifed config in a way that others might need same configuration, consider making new example. + +### Enable basic config + +``` bash +$ ovpn enconf basic_nat +``` + +## ovpn pki + +This command handles PKI, which is needed for using TLS on server. + +``` bash +$ ovpn pki help +Usage: ovpn_pki COMMAND + +Commands: + delete|remove # Removes PKI + init [nopass] # Init PKI (in /config/pki) +``` + +**Note:** Best practise is to use password for your PKI. Password is only needed for signing new certificates (when adding new clients). If you don't want your PKI certificate protected with password, add `nopass` parameter. +**Note:** In this process you need to enter PKI password serveral times, because a lot of things are generated. diff --git a/docs/README.md b/docs/README.md index 0cce3e8..cd51976 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,88 +2,5 @@ ## Table of content -1. Commands - +- [Commands](Commands.md) - [Simple setup guide](SetupGuide.md) - -## Commands - -This section explains commands available for use. - -### Command List - -|**Command**|**Description**| -|:---------:|:-------------:| -|`ovpn_backup`|Backups your configration| -|`ovpn_client`|Manages clients| -|`ovpn_disconf`|Deletes active OpenVPN config| -|`ovpn_enconf`|Enables OpenVPN config from examples| -|`ovpn_init`|Inits PKI| - -#### ovpn_backup - -This command backups your configration into *.tar.gz* archive and puts it into `/config/backup` directory. - -``` -Usage: ovpn_backup COMMAND - -Commands: - all # Backup whole config directory" - pki # Backup PKI files" - hooks # Backup hooks" - openvpn # Backup openvpn live config" -``` - -**Note:** Store your backups in a **SECURE** way, because they are unecrypted. - -#### ovpn_client - -This commands manages clients of your OpenVPN server. - -``` -Usage: ovpn_client COMMAND [ARGS] - -Commands: - add [NAME [nopass]] # Creates certificates for client - ovpn NAME # Builds .ovpn file - revoke|ban|delete|remove NAME # Removes client -``` - -**Note:** First you need to use `add` to create client certificates, before you can use `ovpn` command. - -#### ovpn_disconf - -This command deletes your active configuration. **Container restart** is needed for changes to take affect. - -``` -Usage: ovpn_disconf -``` - -**NOTE:** This command does not delete PKI. - -#### ovpn_enconf - -This command enables OpenVPN config based on config example. If config name isn't specified it prints out config list. - -``` -Usage: ovpn_enconf CONFIG_NAME [wizard args...] - -Configs: - -``` - -**Note:** Please read example documentation to understand how to use it. -**Warning:** Some examples automaticaly add firewall rules, so if you are using host networking make sure to check **iptables** for correct configuration. -**Tip:** If you modifed config in a way that others might need same configuration, consider making new example. - -#### ovpn_init - -This command inits your PKI in `/config/pki` folder. You need to run this command only once. - -``` -Usage: ovpn_init [nopass] -``` - -**Note:** Best practise is to use password for your PKI. Password is only needed for signing new certificates (when adding new clients). If you don't want your PKI certificate protected with password, add `nopass` parameter. -**Note:** In this process you need to enter PKI password serveral times, because a lot of things are generated. - diff --git a/docs/SetupGuide.md b/docs/SetupGuide.md index b714a9c..837f488 100644 --- a/docs/SetupGuide.md +++ b/docs/SetupGuide.md @@ -14,7 +14,7 @@ This is simple setup guide to help you get started. It uses the simplest configu 2. At this point you will have bash shell which runs in container. Now run following commands to **setup your PKI**: ``` bash - ovpn_init [nopass] # Inits PKI + ovpn pki init [nopass] # Inits PKI #CA settings are located in /config/ssl/vars #Did you modified the file or are you planing to enter values interactively ? #[y/N]: y @@ -94,7 +94,7 @@ This is simple setup guide to help you get started. It uses the simplest configu 3. Setup OpenVPN config based on example `basic_nat` with configuration wizard: ``` bash - ovpn_enconf basic_nat + ovpn enconf basic_nat #Out interface [eth0]: #Protocol udp, tcp, udp6, tcp6 [udp]: #VPN network [10.0.0.0]: @@ -111,16 +111,16 @@ This is simple setup guide to help you get started. It uses the simplest configu ``` bash # Generates client certificates - ovpn_client add [nopass] + ovpn client add [nopass] - # Generates client config file and prints it to screen (redirect to file) - ovpn_client ovpn > .ovpn + # Generates client config file and saves it to /config/tmp + ovpn client ovpn # OR BETTER SOLLUTION: Run outside container - docker exec -it ovpn_client ovpn > .ovpn + docker exec -it ovpn client ovpnp > .ovpn ``` -**Note:** Client config files MUST be transported to your devices via **SECURE** methon such as USB (email is considered **INSECURE**). +**Note:** Client config files MUST be transported to your devices via **SECURE** method such as USB (email is considered **INSECURE**). 5. Exit container with `exit`, then it will destroy itself. 6. Now you can create config file outside container, mentioned above. diff --git a/hooks/build b/hooks/build index 26a5952..15ba3d1 100644 --- a/hooks/build +++ b/hooks/build @@ -9,8 +9,8 @@ echo "Building image" docker build \ - --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ - --build-arg VCS_REF=`git rev-parse --short HEAD` \ - --build-arg VCS_SRC="https://github.com/SloCompTech/docker-openvpn/commit/$SOURCE_COMMIT" \ - --build-arg VERSION="$SOURCE_BRANCH" \ - -t $IMAGE_NAME . \ No newline at end of file + --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ + --build-arg VCS_REF=`git rev-parse --short HEAD` \ + --build-arg VCS_SRC="https://github.com/SloCompTech/docker-openvpn/commit/$SOURCE_COMMIT" \ + --build-arg VERSION="$SOURCE_BRANCH" \ + -t $IMAGE_NAME . \ No newline at end of file diff --git a/root/app/bin/ovpn_backup b/root/app/bin/ovpn_backup deleted file mode 100755 index 6ecc905..0000000 --- a/root/app/bin/ovpn_backup +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -# -# Backup sciript -# - -ARCHIVE_CMD="tar --exclude=$OVPN_ROOT/backup -zcvf" - -# User permission fix -if [ "$USER" != "abc" ]; then - RUNAS="sudo -E -u abc" -else - RUNAS="" -fi - -function usage() { - echo "Usage: ovpn_backup COMMAND" - echo "" - echo "Commands:" - echo " all # Backup whole config directory" - echo " pki # Backup PKI files" - echo " hooks # Backup hooks" - echo " openvpn # Backup openvpn live config" -} - -if [ $# -lt 1 ] || [ $1 = "help" ] || [ $1 = "-h" ] || [ $1 = "--help" ]; then - usage - exit 1 -fi - - - -if [ $1 = "all" ]; then - $RUNAS $ARCHIVE_CMD $OVPN_ROOT/backup/backup_all_$(date +%H%M%S%d%m%Y).tar.gz $OVPN_ROOT -elif [ $1 = "pki" ]; then - $RUNAS $ARCHIVE_CMD $OVPN_ROOT/backup/backup_pki_$(date +%H%M%S%d%m%Y).tar.gz $EASYRSA_PKI $OVPN_ROOT/ssl -elif [ $1 = "hooks" ]; then - $RUNAS $ARCHIVE_CMD $OVPN_ROOT/backup/backup_hooks_$(date +%H%M%S%d%m%Y).tar.gz $OVPN_HOOKS -elif [ $1 = "openvpn" ]; then - $RUNAS $ARCHIVE_CMD $OVPN_ROOT/backup/backup_conf_$(date +%H%M%S%d%m%Y).tar.gz $OVPN_ROOT/openvpn -else - usage - exit 1 -fi \ No newline at end of file diff --git a/root/app/bin/ovpn_client b/root/app/bin/ovpn_client deleted file mode 100755 index 36bae42..0000000 --- a/root/app/bin/ovpn_client +++ /dev/null @@ -1,120 +0,0 @@ -#!/bin/bash - -# -# OpenVPN client configuration generator -# - -source /app/lib/utils - -# User permission fix -if [ "$USER" != "abc" ]; then - RUNAS="sudo -E -u abc" -else - RUNAS="" -fi - -function usage() { - echo "Usage: ovpn_client COMMAND [ARGS]" - echo "" - echo "Commands:" - echo " add [NAME [nopass]] # Creates certificates for client" - echo " ovpn NAME # Builds .ovpn file" - echo " revoke|ban|delete|remove NAME # Removes client" -} - -function build_ovpn() { - if [ $# -gt 0 ]; then - # Client standard config - for file in $OVPN_ROOT/openvpn/client/*.conf - do - [ -e "$file" ] || continue - cat $file - done - - # Check if server config is using tls-crypt or tls-auth - local crypto="" - for srv_file in $OVPN_ROOT/openvpn/server/*.conf - do - crypto="$(ovpn_findopt $srv_file tls-crypt tls-auth)" - if [ -n "$crypto" ]; then - break - fi - done - - # CA - echo "" - cat $EASYRSA_PKI/ca.crt - echo "" - echo "" - - # Client certs - echo "" - cat $EASYRSA_PKI/issued/$1.crt - echo "" - - # Client key - echo "" - cat $EASYRSA_PKI/private/$1.key - echo "" - - if [ "$crypto" = "tls-crypt" ]; then - # tls-crypt - echo "" - cat $EASYRSA_PKI/ta.key - echo "" - elif [ "$crypto" = "tls-auth" ]; then - # tls-auth - echo "" - cat $EASYRSA_PKI/ta.key - echo "" - fi - fi -} - -# Check if command even set -if [ $# -lt 1 ]; then - # Invalid command - usage - exit 1 -fi - -if [ "$1" = "add" ]; then - if [ $# -eq 1 ]; then - # Cert guide - read -p "Common name:" CN - echo -n "Password protect " - P=$(yn) - if [ $P -eq 0 ]; then - $RUNAS easyrsa gen-req $CN nopass - else - $RUNAS easyrsa gen-req $CN - fi - $RUNAS easyrsa sign-req client $CN - else - # Just build cert - $RUNAS easyrsa gen-req ${@:2} - $RUNAS easyrsa sign-req client ${@:2} - fi - -elif [ "$1" = "ovpn" ]; then - if [ $# -eq 2 ]; then - build_ovpn $2 - else - usage - exit 1 - fi -elif [ "$1" = "ban" ] || [ "$1" = "remove" ] || [ "$1" = "delete"] || [ "$1" = "revoke" ] ; then - if [ $# -eq 2 ]; then - $RUNAS easyrsa revoke $2 - $RUNAS easyrsa gen-crl - else - usage - exit 1 - fi -else - usage - exit 1 -fi - - - diff --git a/root/app/bin/ovpn_disconf b/root/app/bin/ovpn_disconf deleted file mode 100755 index 91811b2..0000000 --- a/root/app/bin/ovpn_disconf +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -# -# Disables OpenVPN config -# WARNING: This deletes active OpenVPN config & active hooks (/config/hooks) -# - -# Display notice -echo "This script will clear your configuration (whole openvpn directory)." -echo "Please make sure that you backed up you config and active hooks." - -# Make sure that user understands -read -p "Are you sure, you want to delete active config and hooks ? [y/N]:" sure - -# Check if operation aborted -if [ $sure != "y" ] && [ $sure != "Y" ]; then - exit 0 -fi - -# Check if config directory exists -config_path=$OVPN_ROOT/openvpn -if [ ! -d "$config_path" ]; then - echo "Config directory: $config_path does not exist" - exit 1 -fi - -# Delete server config -if [ -d "$config_path/server" ]; then - rm -rf $config_path/server/* -fi - -# Delete client config -if [ -d "$config_path/client" ]; then - rm -rf $config_path/client/* -fi - -# Delete hook scripts -if [ -d "$OVPN_ROOT/hooks" ]; then - rm -rf $OVPN_ROOT/hooks/*/* -fi \ No newline at end of file diff --git a/root/app/bin/ovpn_enconf b/root/app/bin/ovpn_enconf deleted file mode 100755 index 303fe11..0000000 --- a/root/app/bin/ovpn_enconf +++ /dev/null @@ -1,189 +0,0 @@ -#!/bin/bash - -# -# Enables OpenVPN config example -# - -source /app/lib/utils - -# User permission fix -if [ "$USER" != "abc" ]; then - RUNAS="sudo -E -u abc" -else - RUNAS="" -fi - -function usage() { - echo "Usage: ovpn_enconf CONFIG_NAME [wizard args...]" - echo "" - echo "Configs:" - local identifiers=() # Which identifiers we already printed out - - # Go through all identifiers - for folder in $OVPN_ROOT/example/config/* - do - [ -d "$folder" ] || continue - - local folder_name="$(echo $folder | sed -E 's/^\/.*\/(.*)$/\1/')" - - # Check if we already printed out that identifer - local found=0 - for i in "$identifiers" - do - if [ "$i" = "$folder_name" ]; then - found=1 - break - fi - done - if [ $found -eq 0 ]; then - # Print out new identifier - echo "$folder_name" - identifiers=($identifiers $folder_name) - fi - done -} - -# -# Install OpenVPN server configs -# @param source root -# @param dest root -# -function install_server() { - if [ $# -ne 2 ]; then - echo "Wrong usage: install_server" - exit 2 - fi - - # Copy server config - if [ -d $1/server ]; then - # Check if destination folder exists - if [ ! -d "$2/server" ]; then - echo "$2/server does not exist" - exit 3 - fi - - $RUNAS cp -r $1/server/* $2/server - fi -} - -# -# Install OpenVPN client configs -# @param source root -# @param dest root -# -function install_client() { - if [ $# -ne 2 ]; then - echo "Wrong usage: install_client" - exit 2 - fi - - # Copy client config - if [ -d $1/client ]; then - # Check if destination folder exists - if [ ! -d "$2/client" ]; then - echo "$2/client does not exist" - exit 3 - fi - - $RUNAS cp -r $1/client/* $2/client - fi -} - -# -# Install hooks -# @param source root -# @param dest root -# -function install_hooks() { - if [ $# -ne 2 ]; then - echo "Wrong usage: install_hooks" - exit 2 - fi - - # Copy hooks - if [ -d "$1/hooks" ]; then - # Check if destination folder exists - if [ ! -d "$2/hooks" ]; then - echo "$2/hooks does not exist" - exit 3 - fi - - # Hooks directory exist, check for hooks - for conf_hook in $1/hooks/* - do - # We are only interested in directories inside hook folder - [ -d $conf_hook ] || continue - - hook_name="$(echo $folder | sed -E 's/^\/.*\/(.*)$/\1/')" - - # Skip hooks that are not in /config/hooks - if [ ! -d "$2/hooks/$hook_name" ]; then - echo "Hook $hook_name not found in hooks directory." - continue - fi - - # Copy hooks - $RUNAS cp -r $1/hooks/$hook_name/* $2/hooks/$hook_name - done - fi -} - -if [ $# -lt 1 ]; then - usage - exit 1 -fi - -if [ $# -gt 0 ]; then - # Get wanted config name - config_name=$1 - config_path=$OVPN_ROOT/example/config/$config_name - - # Check if config exists - if [ ! -d $config_path ]; then - echo "Config does not exist" - exit 2 - fi - - # TODO: Check if there is any previous config - - # Configure copy destination - if [ -f "$config_path/wizard" ] && [ -x "$config_path/wizard" ]; then - tmp_path=/tmp/wizard - - # Delete existing tmp directory - if [ -e "$tmp_path" ]; then - rm -rf $tmp_path - fi - - # Copy config to temporary folder so it can be modified - $RUNAS cp -r $config_path $tmp_path - - # Run wizard (with temporary path) - $RUNAS $config_path/wizard "$tmp_path" ${@:2} - exit_code=$? - - # If wizard exists with code other than 0, return error - if [ $exit_code -ne 0 ]; then - echo "Error while executing wizard" - exit $exit_code - fi - - # Copy wizard finished files - install_server $tmp_path $OVPN_ROOT/openvpn - install_client $tmp_path $OVPN_ROOT/openvpn - install_hooks $tmp_path $OVPN_ROOT - - # Remove temporary directory - rm -rf $tmp_path - else - # Directly copy files - install_server $config_path $OVPN_ROOT/openvpn - install_client $config_path $OVPN_ROOT/openvpn - install_hooks $config_path $OVPN_ROOT - - # Wizard not available - echo "Sorry, wizard not available for this config" - echo "" - echo "Please edit config files in /config/openvpn to suite your needs" - fi -fi \ No newline at end of file diff --git a/root/app/bin/ovpn_findopt b/root/app/bin/ovpn_findopt deleted file mode 100644 index 3baf67a..0000000 --- a/root/app/bin/ovpn_findopt +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/python - -# -# Finds first of specified options in config file -# @author Martin Dagarin -# @version 1 -# @since 19/03/2019 -# -# Usage: ovpn_findopt ... -# -import sys - -# Import libraries included in this docker -sys.path.insert(0, '/app/lib') -import libovpn - -if len(sys.argv) < 3: - # Invalid command - print("") - sys.exit(0) - -config_file = sys.argv[1] -found = libovpn.conf_optFindFirst(config_file, sys.argv[2:]) - -if found is not None: - print(found) -else: - print("") \ No newline at end of file diff --git a/root/app/bin/ovpn_init b/root/app/bin/ovpn_init deleted file mode 100755 index d8befb9..0000000 --- a/root/app/bin/ovpn_init +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash - -# -# OpenVPN init script -# -# @see https://community.openvpn.net/openvpn/wiki/EasyRSA3-OpenVPN-Howto -# @see https://forums.openvpn.net/viewtopic.php?t=20837 -# @see https://securitronlinux.com/bejiitaswrath/how-to-create-keys-with-easy-rsa-without-a-password-prompt/ -# -# Usage: ovpn_init [nopass] -# -# - -# User permission fix -if [ "$USER" != "abc" ]; then - RUNAS="sudo -E -u abc" -else - RUNAS="" -fi - -# -# Init CA -# -if [ -e "$OVPN_ROOT/pki" ] && [ ! -n "$OVPN_INIT_PKI"]; then - echo "PKI directory already exists. Are you SURE to init PKI again ?" - echo "You will LOSE all files in your PKI." - echo -n "[y/N]:" - read decission - if [ $decission == "y" ] || [ $decission == "Y" ]; then - # Delete PKI - rm -rf $EASYRSA_PKI - else - # Abort - exit 0 - fi -else - echo "CA settings are located in $EASYRSA_VARS_FILE" - echo "Did you modified the file or are you planing to enter values interactively ?" - echo -n "[y/N]:" - read decission - if [ $decission != "y" ] && [ $decission != "Y" ]; then - echo "Please edit $EASYRSA_VARS_FILE" - exit 0 - fi -fi - -# Init PKI directory -$RUNAS easyrsa init-pki - -# Build dh.pem -$RUNAS easyrsa gen-dh - -# Build CA -echo "Now it will build CA files for issuing new certifiactes" -echo "Please protect ca.key with secure password (used for signing new certs)" -echo "ca.key is needed only for signing new certificates, not for OpenVPN to work" - -if [ $# -gt 0 ] && [ $1 == "nopass" ]; then - $RUNAS easyrsa build-ca nopass -else - $RUNAS easyrsa build-ca -fi - -# Build server key -$RUNAS easyrsa build-server-full server nopass -$RUNAS easyrsa sign-req server server -rm $EASYRSA_PKI/reqs/server.req - -# Generate ta.key (for tls-auth,tls-crypt) -$RUNAS openvpn --genkey --secret $EASYRSA_PKI/ta.key - -# Generate CRL -$RUNAS easyrsa gen-crl diff --git a/root/app/bin/run_hooks b/root/app/bin/run_hooks deleted file mode 100755 index c0e75b5..0000000 --- a/root/app/bin/run_hooks +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -# -# Run hook scripts -# - -OVPN_HOOKS=${OVPN_HOOKS:-/config/hooks} - -function usage() { - echo "Usage: run_hooks HOOK_NAME [ARGS]" - echo "" - echo "Hooks:" - echo " auth On OpenVPN client authentication" - echo " client-connect On OpenVPN client connected" - echo " client-disconnect On OpenVPN client disconnected" - echo " finish On container shutdown" - echo " init On container power on" - echo " learn-address Client Address & Routes validation" - echo " down Before/After TUN interface closed" - echo " route-up After routes are added" - echo " route-pre-down Before routes are removed" - echo " tls-verify On OpenVPN client certificate verificaton" - echo " up After TUN interface opened" -} - -# Check if hook name is set -if [ ! -n "$1" ]; then - usage - exit 1 -fi - -# Check if hook directory exist -if [ ! -d "$OVPN_HOOKS/$1" ]; then - echo "Hook $OVPN_HOOKS/$1 directory does not exist" - exit 2 -fi - -# Run each script and check for return code -for script in $OVPN_HOOKS/$1/*; do - [ -e "$script" ] || continue - - # Execute only executable files - if [ -f "$script" ] && [ -x "$script" ]; then - # Run script and pass additional args to hooks - echo "Executing hook: $script" - if [ $# -gt 2 ]; then - $script ${@:2} - else - $script - fi - - # Check for error while executing script - exit_status=$? - if [ $exit_status -ne 0 ]; then - # In case one of the hook files fails, everything fails - echo "$script exited with $exit_status." - exit $exit_status - fi - fi -done - -# Exit with success -exit 0 \ No newline at end of file diff --git a/root/app/hookBaseFirewall.sh b/root/app/hookBaseFirewall.sh new file mode 100644 index 0000000..6418892 --- /dev/null +++ b/root/app/hookBaseFirewall.sh @@ -0,0 +1,20 @@ +#!/usr/bin/with-contenv bash + +# +# Pre-checks for firewall related hooks +# + +# Check if firewall rules are disabled +if [ "$USE_FIREWALL" == "false" ]; then + exit 0 # Don't use fw rules +fi + +# Run script only once if persistent interface +# @see https://stackoverflow.com/questions/4774054/reliable-way-for-a-bash-script-to-get-the-full-path-to-itself +if [ "$PERSISTENT_INTERFACE" == "true" ]; then + flagFile="$(realpath $0).flag" + if [ -f "$flagFile" ]; then + exit 0 # Flag file exists, exit + fi + touch $flagFile +fi \ No newline at end of file diff --git a/root/app/lib/settings b/root/app/lib/settings deleted file mode 100644 index 0d46f2d..0000000 --- a/root/app/lib/settings +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/with-contenv bash - -# -# Settings functions -# - -# -# Checks if TUN interface is supposed to be persistant -# @return 1 if persistant, 0 if not -# -function intPersistant() { - if [ ! -n "$OVPN_PERINT" ] || ([ "$OVPN_PERINT" != "true" ] && [ "$OVPN_PERINT" != "1" ]); then - return 0 # Not persistant by default - else - return 1 # Persistant - fi -} - -# -# Checks if we use firewall rules -# @return 1 if yes, 0 if not -# -function useFW() { - if [ ! -n "$OVPN_NFW" ] || ([ "$OVPN_NFW" != "true" ] && [ "$OVPN_NFW" != "1" ]); then - return 1 # yes by default - else - return 0 # No - fi -} - -# -# Checks if TUN interface exists already -# @return 0 if found, 1 if not found -# -function intTunExists() { - RES=`cat /proc/net/dev | grep tun0` - if [ -n "$RES" ]; then - return 0 # Found - else - return 1 # Not found - fi -} \ No newline at end of file diff --git a/root/app/lib/utils b/root/app/lib/utils deleted file mode 100644 index 9706a15..0000000 --- a/root/app/lib/utils +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/with-contenv bash - -# -# Additional functions -# - -function yn() { - local defaultOption=${1:-'n'} - local defaultText='[y/N]:' - if [ defaultOption = 'y' ]; then - defaultText='[Y/n]:' - fi - read -p "$defaultText" decision - if [ "$decision" = 'y' ] || [ "$decision" = 'Y' ]; then - echo '1' - else - echo '0' - fi -} - -# -# Checks if item is in array -# @param $1 Array as "${array[@]}" -# @param $2 String we are looking for -# @return 0 If not in array, 1 if in array -# -# arrayContains array "element" -# echo $? -# -function arrayContains() { - # Check if empty - if [ ! -n "$1" ]; then - return 0 - fi - - local array="$1[@]" - # Check array for element - for element in "${!array}"; do - - # Check if we found element in array - if [ "$2" = "$element" ]; then - return 1 - fi - done - - # Element not found - return 0 -} - -# -# Function that makes sure, that script runs only once -# @param $1 ID -# -function run_once() { - if [ -f "$1" ]; then # Check if file (as flag) exists - exit 0 - fi - touch $1 # Create flag - chown abc:abc $1 # Change permission -} \ No newline at end of file diff --git a/root/app/lib/libovpn.py b/root/app/libovpn.py similarity index 100% rename from root/app/lib/libovpn.py rename to root/app/libovpn.py diff --git a/root/defaults/example/README.md b/root/defaults/example/README.md index 93e03a4..1255f25 100644 --- a/root/defaults/example/README.md +++ b/root/defaults/example/README.md @@ -23,39 +23,31 @@ Config directory has following structure: ``` config - # Directory with your examples - client # Directory, OpenVPN client config files - .conf # Partial OpenVPN client config file - server # Directory, OpenVPN server config files - .conf # Partial OpenVPN server config file - hooks # Directory with hooks for this example - # Directory, name of hook - # Executable scripts - wizard # Setup script, run on `ovpn_enconf` command. - Readme.md # Info about example, what to configure + # Directory with your examples + client # Directory, OpenVPN client config files + .conf # Partial OpenVPN client config file + server # Directory, OpenVPN server config files + .conf # Partial OpenVPN server config file + hooks # Directory with hooks for this example + # Directory, name of hook + # Executable scripts + wizard # Setup script, run on `ovpn_enconf` command. + Readme.md # Info about example, what to configure ``` ### Hooks - start hook file with - ``` bash - #!/usr/bin/with-contenv bash - - source /app/lib/settings - source /app/lib/utils - ``` + ``` bash + #!/usr/bin/with-contenv bash + ``` - if hooks call any **firewall** related commands add after above code and before any commands - ``` bash - # Check if firewall rules are disabled - useFW - if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 - fi - ``` + ``` bash + source /app/hookBaseFirewall.sh + ``` - also check the examples how persistent interface is handled, so you don't create iptables mess (running init, up script once, never call down, finish) @@ -70,16 +62,16 @@ config ### Wizard Wizard is script that helps user to simply configure your example to his needs. -User will call `ovpn_enconf CONFIG_NAME [wizard args]` to load your example in server config. +User will call `ovpn enconf CONFIG_NAME [wizard args]` to load your example in server config. Then there are two options: 1. User manualy configure settings in `/config/openvpn` folder 2. Your **wizard** script, configures files which will be copied to `/config/openvpn` - - Configuration files are copied to temporary location (so they can be modified) - - `wizard` script will be called with temporary location as first argument `$1` (folder has same structure as in examples) - - Your `wizard` script **MUST** only modify files in temporary location. - - When your wizard exits with code 0, files are copied from temporary location to config folder. + - Configuration files are copied to temporary location (so they can be modified) + - `wizard` script will be called with temporary location as first argument `$1` (folder has same structure as in examples) + - Your `wizard` script **MUST** only modify files in temporary location. + - When your wizard exits with code 0, files are copied from temporary location to config folder. ## General hooks @@ -90,8 +82,8 @@ Hooks are located in `hook` directory. Please follow hook guidelines: - File name: **hook_\** - At the top of the script - - Optionaly copyright notice - - What this hook does - - Setttings with comments and an example settings values + - Optionaly copyright notice + - What this hook does + - Setttings with comments and an example settings values -**Note:** All hooks run as non-root user so instead of using `ip` and `iptables` use `ovpn-ip`, `ovpn-iptables`, `ovpn-ip6tables` (see [/root/usr/local/sbin](/usr/local/sbin)). \ No newline at end of file +**Note:** All hooks run as non-root user so instead of using `ip` and `iptables` use `ovpn-ip`, `ovpn-iptables`, `ovpn-ip6tables` (see [/root/usr/local/sbin](/usr/local/sbin)). diff --git a/root/defaults/example/config/basic_nat/README.md b/root/defaults/example/config/basic_nat/README.md index 8c86c80..a8ef966 100644 --- a/root/defaults/example/config/basic_nat/README.md +++ b/root/defaults/example/config/basic_nat/README.md @@ -17,4 +17,4 @@ ovpn_enconf basic_nat #Public IP or domain of server: #DNS1 [8.8.8.8]: #DNS2 [8.8.4.4]: -``` \ No newline at end of file +``` diff --git a/root/defaults/example/config/basic_nat/client/client.conf b/root/defaults/example/config/basic_nat/client/client.conf index 88587cc..271ab49 100644 --- a/root/defaults/example/config/basic_nat/client/client.conf +++ b/root/defaults/example/config/basic_nat/client/client.conf @@ -34,4 +34,3 @@ group nogroup # CA remote-cert-tls server - diff --git a/root/defaults/example/config/basic_nat/server/server.conf b/root/defaults/example/config/basic_nat/config/server.conf similarity index 100% rename from root/defaults/example/config/basic_nat/server/server.conf rename to root/defaults/example/config/basic_nat/config/server.conf diff --git a/root/defaults/example/config/basic_nat/hooks/down/10-network.sh b/root/defaults/example/config/basic_nat/hooks/down/10-network.sh index b965678..23255ec 100755 --- a/root/defaults/example/config/basic_nat/hooks/down/10-network.sh +++ b/root/defaults/example/config/basic_nat/hooks/down/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Don't run if interface persistent -intPersistant -if [ $? -eq 1 ]; then - exit 0 -fi +source /app/hookBaseFirewall.sh # # Network clear @@ -35,4 +21,3 @@ ovpn-iptables -D FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m # Disable NAT for VPN traffic ovpn-iptables -t nat -D POSTROUTING -s $NETWORK_ADDRESS/24 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" - diff --git a/root/defaults/example/config/basic_nat/hooks/finish/10-network.sh b/root/defaults/example/config/basic_nat/hooks/finish/10-network.sh index 94e74cd..dc6699b 100755 --- a/root/defaults/example/config/basic_nat/hooks/finish/10-network.sh +++ b/root/defaults/example/config/basic_nat/hooks/finish/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Don't run if interface persistent -intPersistant -if [ $? -eq 1 ]; then - exit 0 -fi +source /app/hookBaseFirewall.sh # # Network clear @@ -31,4 +17,4 @@ ovpn-iptables -D INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m c ovpn-iptables -D INPUT -p icmp --icmp-type 8 -j ACCEPT # Accept all forwarded traffic -ovpn-iptables -P FORWARD ACCEPT \ No newline at end of file +ovpn-iptables -P FORWARD ACCEPT diff --git a/root/defaults/example/config/basic_nat/hooks/init/10-network.sh b/root/defaults/example/config/basic_nat/hooks/init/10-network.sh index 890870e..e127050 100755 --- a/root/defaults/example/config/basic_nat/hooks/init/10-network.sh +++ b/root/defaults/example/config/basic_nat/hooks/init/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Run only once if interface persistent -intPersistant -if [ $? -eq 1 ]; then - run_once "/config/hooks/init/10-network" -fi +source /app/hookBaseFirewall.sh # # Network initialization @@ -36,4 +22,4 @@ ovpn-iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m c ovpn-iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # Drop all forwarded traffic -ovpn-iptables -P FORWARD DROP \ No newline at end of file +ovpn-iptables -P FORWARD DROP diff --git a/root/defaults/example/config/basic_nat/hooks/up/10-network.sh b/root/defaults/example/config/basic_nat/hooks/up/10-network.sh index 228b553..f170cc2 100755 --- a/root/defaults/example/config/basic_nat/hooks/up/10-network.sh +++ b/root/defaults/example/config/basic_nat/hooks/up/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Run only once if interface persistent -intPersistant -if [ $? -eq 1 ]; then - run_once "/config/hooks/up/10-network" -fi +source /app/hookBaseFirewall.sh # # Network initialization @@ -35,4 +21,3 @@ ovpn-iptables -A FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m # Preform NAT for VPN traffic ovpn-iptables -t nat -A POSTROUTING -s $NETWORK_ADDRESS/24 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" - diff --git a/root/defaults/example/config/basic_nat/wizard b/root/defaults/example/config/basic_nat/wizard index f797867..e2bc98c 100755 --- a/root/defaults/example/config/basic_nat/wizard +++ b/root/defaults/example/config/basic_nat/wizard @@ -17,7 +17,7 @@ import sys, os # Import libraries included in this docker -sys.path.insert(0, '/app/lib') +sys.path.insert(0, '/app') import libovpn # Check if temporary path was passed to this script @@ -46,45 +46,45 @@ if len(protocol) == 0: # Select network network = input("VPN network [10.0.0.0]:") if len(network) == 0: - network = "10.0.0.0" + network = "10.0.0.0" # Select port port = input("Port [1194]:") if len(port) == 0: - port="1194" + port="1194" # Select Public IP or domain public = input("Public IP or domain of server:") if len(public) == 0: - print("Invalid Public IP") - sys.exit(4) + print("Invalid Public IP") + sys.exit(4) # DNS servers dns1 = input("DNS1 [8.8.8.8]:") if len(dns1) == 0: - dns1 = "8.8.8.8" + dns1 = "8.8.8.8" dns2 = input("DNS2 [8.8.4.4]:") if len(dns2) == 0: - dns2 = "8.8.4.4" + dns2 = "8.8.4.4" # Write to server config vars = [ - ("$OUT_INT", out_int), - ("$PROTO", protocol), - ("$PORT", port), - ("$NETWORK_ADDRESS", network), - ("$SERVER_IP", public), - ("$DNS1", dns1), - ("$DNS2", dns2) + ("$OUT_INT", out_int), + ("$PROTO", protocol), + ("$PORT", port), + ("$NETWORK_ADDRESS", network), + ("$SERVER_IP", public), + ("$DNS1", dns1), + ("$DNS2", dns2) ] # Process config files confs = [ - "/server/server.conf", - "/client/client.conf", - "/hooks/down/10-network.sh", - "/hooks/up/10-network.sh" + "/config/server.conf", + "/client/client.conf", + "/hooks/down/10-network.sh", + "/hooks/up/10-network.sh" ] for config_file in confs: - libovpn.conf_envsubst(TEMP_PATH + config_file, vars) \ No newline at end of file + libovpn.conf_envsubst(TEMP_PATH + config_file, vars) \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat_wlp/README.md b/root/defaults/example/config/basic_nat_wlp/README.md index 256e8df..0e4ea53 100644 --- a/root/defaults/example/config/basic_nat_wlp/README.md +++ b/root/defaults/example/config/basic_nat_wlp/README.md @@ -17,4 +17,4 @@ ovpn_enconf basic_nat_wlp #Public IP or domain of server: #DNS1 [8.8.8.8]: #DNS2 [8.8.4.4]: -``` \ No newline at end of file +``` diff --git a/root/defaults/example/config/basic_nat_wlp/client/client.conf b/root/defaults/example/config/basic_nat_wlp/client/client.conf index 88587cc..271ab49 100644 --- a/root/defaults/example/config/basic_nat_wlp/client/client.conf +++ b/root/defaults/example/config/basic_nat_wlp/client/client.conf @@ -34,4 +34,3 @@ group nogroup # CA remote-cert-tls server - diff --git a/root/defaults/example/config/basic_nat_wlp/server/server.conf b/root/defaults/example/config/basic_nat_wlp/config/server.conf similarity index 100% rename from root/defaults/example/config/basic_nat_wlp/server/server.conf rename to root/defaults/example/config/basic_nat_wlp/config/server.conf diff --git a/root/defaults/example/config/basic_nat_wlp/hooks/down/10-network.sh b/root/defaults/example/config/basic_nat_wlp/hooks/down/10-network.sh index 746ba15..6f61b5a 100755 --- a/root/defaults/example/config/basic_nat_wlp/hooks/down/10-network.sh +++ b/root/defaults/example/config/basic_nat_wlp/hooks/down/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Don't run if interface persistent -intPersistant -if [ $? -eq 1 ]; then - exit 0 -fi +source /app/hookBaseFirewall.sh # # Network clear @@ -30,4 +16,3 @@ ovpn-iptables -D FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m # Disable NAT for VPN traffic ovpn-iptables -t nat -D POSTROUTING -s $NETWORK_ADDRESS/24 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" - diff --git a/root/defaults/example/config/basic_nat_wlp/hooks/finish/10-network.sh b/root/defaults/example/config/basic_nat_wlp/hooks/finish/10-network.sh index 94e74cd..ab24e9f 100755 --- a/root/defaults/example/config/basic_nat_wlp/hooks/finish/10-network.sh +++ b/root/defaults/example/config/basic_nat_wlp/hooks/finish/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Don't run if interface persistent -intPersistant -if [ $? -eq 1 ]; then - exit 0 -fi +source /app/hookBaseFirewall.sh # # Network clear diff --git a/root/defaults/example/config/basic_nat_wlp/hooks/init/10-network.sh b/root/defaults/example/config/basic_nat_wlp/hooks/init/10-network.sh index 890870e..0405102 100755 --- a/root/defaults/example/config/basic_nat_wlp/hooks/init/10-network.sh +++ b/root/defaults/example/config/basic_nat_wlp/hooks/init/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Run only once if interface persistent -intPersistant -if [ $? -eq 1 ]; then - run_once "/config/hooks/init/10-network" -fi +source /app/hookBaseFirewall.sh # # Network initialization diff --git a/root/defaults/example/config/basic_nat_wlp/hooks/up/10-network.sh b/root/defaults/example/config/basic_nat_wlp/hooks/up/10-network.sh index 49a166b..f5a92da 100755 --- a/root/defaults/example/config/basic_nat_wlp/hooks/up/10-network.sh +++ b/root/defaults/example/config/basic_nat_wlp/hooks/up/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Run only once if interface persistent -intPersistant -if [ $? -eq 1 ]; then - run_once "/config/hooks/up/10-network" -fi +source /app/hookBaseFirewall.sh # # Network initialization @@ -30,4 +16,3 @@ ovpn-iptables -A FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m # Preform NAT for VPN traffic ovpn-iptables -t nat -A POSTROUTING -s $NETWORK_ADDRESS/24 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" - diff --git a/root/defaults/example/config/basic_nat_wlp/wizard b/root/defaults/example/config/basic_nat_wlp/wizard index a1840a2..6bd45a6 100755 --- a/root/defaults/example/config/basic_nat_wlp/wizard +++ b/root/defaults/example/config/basic_nat_wlp/wizard @@ -17,74 +17,74 @@ import sys, os # Import libraries included in this docker -sys.path.insert(0, '/app/lib') +sys.path.insert(0, '/app') import libovpn # Check if temporary path was passed to this script if len(sys.argv) < 2: - print("Temporary path was not passed to wizard") - sys.exit(1) + print("Temporary path was not passed to wizard") + sys.exit(1) TEMP_PATH = sys.argv[1] if not os.path.isdir(TEMP_PATH): - print("Specified directory does not exist") - sys.exit(2) + print("Specified directory does not exist") + sys.exit(2) # Select output interface out_int = input("Out interface [eth0]:") if len(out_int) == 0: - out_int = "eth0" + out_int = "eth0" # Select protocol protocol = input("Protocol udp, tcp, udp6, tcp6 [udp]:") AVAILABLE_PROTOCOLS = ["udp", "tcp", "udp6", "tcp6"] if len(protocol) != 0 and protocol not in AVAILABLE_PROTOCOLS: - print("Invalid protocol") - sys.exit(3) + print("Invalid protocol") + sys.exit(3) if len(protocol) == 0: - protocol = "udp" + protocol = "udp" # Select network network = input("VPN network [10.0.0.0]:") if len(network) == 0: - network = "10.0.0.0" + network = "10.0.0.0" # Select port port = input("Port [1194]:") if len(port) == 0: - port="1194" + port="1194" # Select Public IP or domain public = input("Public IP or domain of server:") if len(public) == 0: - print("Invalid Public IP") - sys.exit(4) + print("Invalid Public IP") + sys.exit(4) # DNS servers dns1 = input("DNS1 [8.8.8.8]:") if len(dns1) == 0: - dns1 = "8.8.8.8" + dns1 = "8.8.8.8" dns2 = input("DNS2 [8.8.4.4]:") if len(dns2) == 0: - dns2 = "8.8.4.4" + dns2 = "8.8.4.4" # Write to server config vars = [ - ("$OUT_INT", out_int), - ("$PROTO", protocol), - ("$PORT", port), - ("$NETWORK_ADDRESS", network), - ("$SERVER_IP", public), - ("$DNS1", dns1), - ("$DNS2", dns2) + ("$OUT_INT", out_int), + ("$PROTO", protocol), + ("$PORT", port), + ("$NETWORK_ADDRESS", network), + ("$SERVER_IP", public), + ("$DNS1", dns1), + ("$DNS2", dns2) ] # Process config files confs = [ - "/server/server.conf", - "/client/client.conf", - "/hooks/down/10-network.sh", - "/hooks/up/10-network.sh" + "/config/server.conf", + "/client/client.conf", + "/hooks/down/10-network.sh", + "/hooks/up/10-network.sh" ] for config_file in confs: - libovpn.conf_envsubst(TEMP_PATH + config_file, vars) \ No newline at end of file + libovpn.conf_envsubst(TEMP_PATH + config_file, vars) \ No newline at end of file diff --git a/root/defaults/example/config/basic_routed/README.md b/root/defaults/example/config/basic_routed/README.md index 1df5b0b..064a5ff 100644 --- a/root/defaults/example/config/basic_routed/README.md +++ b/root/defaults/example/config/basic_routed/README.md @@ -3,7 +3,7 @@ Features: - Has configuration wizard -- Prepared for using routing (so you will have access to LANs directly without usign NAT) +- Prepared for using routing (so you will have access to LANs directly without using NAT) ## Configure diff --git a/root/defaults/example/config/basic_routed/client/client.conf b/root/defaults/example/config/basic_routed/client/client.conf index 88587cc..271ab49 100644 --- a/root/defaults/example/config/basic_routed/client/client.conf +++ b/root/defaults/example/config/basic_routed/client/client.conf @@ -34,4 +34,3 @@ group nogroup # CA remote-cert-tls server - diff --git a/root/defaults/example/config/basic_routed/server/server.conf b/root/defaults/example/config/basic_routed/config/server.conf similarity index 100% rename from root/defaults/example/config/basic_routed/server/server.conf rename to root/defaults/example/config/basic_routed/config/server.conf diff --git a/root/defaults/example/config/basic_routed/hooks/down/10-network.sh b/root/defaults/example/config/basic_routed/hooks/down/10-network.sh index 2ade89a..181eab9 100755 --- a/root/defaults/example/config/basic_routed/hooks/down/10-network.sh +++ b/root/defaults/example/config/basic_routed/hooks/down/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Don't run if interface persistent -intPersistant -if [ $? -eq 1 ]; then - exit 0 -fi +source /app/hookBaseFirewall.sh # # Network clear @@ -27,4 +13,3 @@ ovpn-iptables -D INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --commen # Disable Routing Internet <--> VPN network ovpn-iptables -D FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" ovpn-iptables -D FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" - diff --git a/root/defaults/example/config/basic_routed/hooks/finish/10-network.sh b/root/defaults/example/config/basic_routed/hooks/finish/10-network.sh index 94e74cd..dc6699b 100755 --- a/root/defaults/example/config/basic_routed/hooks/finish/10-network.sh +++ b/root/defaults/example/config/basic_routed/hooks/finish/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Don't run if interface persistent -intPersistant -if [ $? -eq 1 ]; then - exit 0 -fi +source /app/hookBaseFirewall.sh # # Network clear @@ -31,4 +17,4 @@ ovpn-iptables -D INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m c ovpn-iptables -D INPUT -p icmp --icmp-type 8 -j ACCEPT # Accept all forwarded traffic -ovpn-iptables -P FORWARD ACCEPT \ No newline at end of file +ovpn-iptables -P FORWARD ACCEPT diff --git a/root/defaults/example/config/basic_routed/hooks/init/10-network.sh b/root/defaults/example/config/basic_routed/hooks/init/10-network.sh index 890870e..e127050 100755 --- a/root/defaults/example/config/basic_routed/hooks/init/10-network.sh +++ b/root/defaults/example/config/basic_routed/hooks/init/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Run only once if interface persistent -intPersistant -if [ $? -eq 1 ]; then - run_once "/config/hooks/init/10-network" -fi +source /app/hookBaseFirewall.sh # # Network initialization @@ -36,4 +22,4 @@ ovpn-iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m c ovpn-iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # Drop all forwarded traffic -ovpn-iptables -P FORWARD DROP \ No newline at end of file +ovpn-iptables -P FORWARD DROP diff --git a/root/defaults/example/config/basic_routed/hooks/up/10-network.sh b/root/defaults/example/config/basic_routed/hooks/up/10-network.sh index 0680dd2..8a28d3c 100755 --- a/root/defaults/example/config/basic_routed/hooks/up/10-network.sh +++ b/root/defaults/example/config/basic_routed/hooks/up/10-network.sh @@ -1,20 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/lib/settings -source /app/lib/utils - -# Check if firewall rules are disabled -useFW -if [ $? -eq 0 ]; then - # Don't use fw rules - exit 0 -fi - -# Run only once if interface persistent -intPersistant -if [ $? -eq 1 ]; then - run_once "/config/hooks/up/10-network" -fi +source /app/hookBaseFirewall.sh # # Network initialization @@ -27,4 +13,3 @@ ovpn-iptables -A INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --commen # Allow Routing Internet <--> VPN network ovpn-iptables -A FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" ovpn-iptables -A FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" - diff --git a/root/defaults/example/config/basic_routed/wizard b/root/defaults/example/config/basic_routed/wizard index 1f6e88c..0b9afd7 100755 --- a/root/defaults/example/config/basic_routed/wizard +++ b/root/defaults/example/config/basic_routed/wizard @@ -17,74 +17,74 @@ import sys, os # Import libraries included in this docker -sys.path.insert(0, '/app/lib') +sys.path.insert(0, '/app') import libovpn # Check if temporary path was passed to this script if len(sys.argv) < 2: - print("Temporary path was not passed to wizard") - sys.exit(1) + print("Temporary path was not passed to wizard") + sys.exit(1) TEMP_PATH = sys.argv[1] if not os.path.isdir(TEMP_PATH): - print("Specified directory does not exist") - sys.exit(2) + print("Specified directory does not exist") + sys.exit(2) # Select output interface out_int = input("Out interface [eth0]:") if len(out_int) == 0: - out_int = "eth0" + out_int = "eth0" # Select protocol protocol = input("Protocol udp, tcp, udp6, tcp6 [udp]:") AVAILABLE_PROTOCOLS = ["udp", "tcp", "udp6", "tcp6"] if len(protocol) != 0 and protocol not in AVAILABLE_PROTOCOLS: - print("Invalid protocol") - sys.exit(3) + print("Invalid protocol") + sys.exit(3) if len(protocol) == 0: - protocol = "udp" + protocol = "udp" # Select network network = input("VPN network [10.0.0.0]:") if len(network) == 0: - network = "10.0.0.0" + network = "10.0.0.0" # Select port port = input("Port [1194]:") if len(port) == 0: - port="1194" + port="1194" # Select Public IP or domain public = input("Public IP or domain of server:") if len(public) == 0: - print("Invalid Public IP") - sys.exit(4) + print("Invalid Public IP") + sys.exit(4) # DNS servers dns1 = input("DNS1 [8.8.8.8]:") if len(dns1) == 0: - dns1 = "8.8.8.8" + dns1 = "8.8.8.8" dns2 = input("DNS2 [8.8.4.4]:") if len(dns2) == 0: - dns2 = "8.8.4.4" + dns2 = "8.8.4.4" # Write to server config vars = [ - ("$OUT_INT", out_int), - ("$PROTO", protocol), - ("$PORT", port), - ("$NETWORK_ADDRESS", network), - ("$SERVER_IP", public), - ("$DNS1", dns1), - ("$DNS2", dns2) + ("$OUT_INT", out_int), + ("$PROTO", protocol), + ("$PORT", port), + ("$NETWORK_ADDRESS", network), + ("$SERVER_IP", public), + ("$DNS1", dns1), + ("$DNS2", dns2) ] # Process config files confs = [ - "/server/server.conf", - "/client/client.conf", - "/hooks/down/10-network.sh", - "/hooks/up/10-network.sh" + "/config/server.conf", + "/client/client.conf", + "/hooks/down/10-network.sh", + "/hooks/up/10-network.sh" ] for config_file in confs: - libovpn.conf_envsubst(TEMP_PATH + config_file, vars) \ No newline at end of file + libovpn.conf_envsubst(TEMP_PATH + config_file, vars) \ No newline at end of file diff --git a/root/defaults/system.conf b/root/defaults/openvpn/system.conf similarity index 59% rename from root/defaults/system.conf rename to root/defaults/openvpn/system.conf index f89d548..3a2d557 100644 --- a/root/defaults/system.conf +++ b/root/defaults/openvpn/system.conf @@ -17,15 +17,15 @@ dev tun0 script-security 2 # Hooks call -route-up "/app/bin/run_hooks route-up" -route-pre-down "/app/bin/run_hooks route-pre-down" -up "/app/bin/run_hooks up" +route-up "run_hooks route-up" +route-pre-down "run_hooks route-pre-down" +up "run_hooks up" down-pre -down "/app/bin/run_hooks down" -client-connect "/app/bin/run_hooks client-connect" -client-disconnect "/app/bin/run_hooks client-disconnect" -learn-address "/app/bin/run_hooks learn-address" -tls-verify "/app/bin/run_hooks tls-verify" +down "run_hooks down" +client-connect "run_hooks client-connect" +client-disconnect "run_hooks client-disconnect" +learn-address "run_hooks learn-address" +tls-verify "run_hooks tls-verify" # # For username & password authentication uncomment bellow @@ -36,22 +36,22 @@ tls-verify "/app/bin/run_hooks tls-verify" #--auth-user-pass-optional # Temporary dir -tmp-dir tmp +tmp-dir /config/tmp # Logging verb 3 mute 100 -#log-append log/openvpn.log +#log-append /log/openvpn.log # Status -status log/status 30 +#status /log/status 30 status-version 2 # Client config directory -client-config-dir openvpn/ccd +client-config-dir /config/openvpn/ccd # Certificate revocation list -crl-verify pki/crl.pem +crl-verify /config/pki/crl.pem # Include configs -config include-server.conf +config /config/openvpn/include-conf.conf diff --git a/root/etc/cont-finish.d/60-network b/root/etc/cont-finish.d/60-network deleted file mode 100755 index 4f050d5..0000000 --- a/root/etc/cont-finish.d/60-network +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/with-contenv bash - -source /app/lib/settings - -# -# Network setup -# - -# Delete tunnel interface (if not persistant) -intTunExists -TUNE=$? -intPersistant -PERINT=$? -if [ $TUNE -eq 0 ] && [ $PERINT -eq 0 ]; then # TUN interface exists & !persistant - echo "Removing tun0 interface" - openvpn --rmtun --dev tun0 -fi \ No newline at end of file diff --git a/root/etc/cont-finish.d/60-network.sh b/root/etc/cont-finish.d/60-network.sh new file mode 100755 index 0000000..ee8d03d --- /dev/null +++ b/root/etc/cont-finish.d/60-network.sh @@ -0,0 +1,11 @@ +#!/usr/bin/with-contenv bash + +# +# Network setup +# + +# Delete tunnel interface (if not persistant) +if [ -n "$(cat /proc/net/dev | grep tun0)" ] && { [ -z "$PERSISTENT_INTERFACE" ] || [ "$PERSISTENT_INTERFACE" != "true" ]; }; then + echo "Removing tun0 interface" + openvpn --rmtun --dev tun0 +fi \ No newline at end of file diff --git a/root/etc/cont-finish.d/99-custom_finish b/root/etc/cont-finish.d/99-custom_finish.sh similarity index 100% rename from root/etc/cont-finish.d/99-custom_finish rename to root/etc/cont-finish.d/99-custom_finish.sh diff --git a/root/etc/cont-init.d/20-env b/root/etc/cont-init.d/20-env deleted file mode 100644 index 08ab6df..0000000 --- a/root/etc/cont-init.d/20-env +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/with-contenv bash - -# -# Display environment variables -# - -# Display variables for troubleshooting -echo -e "Variables set:\\n\ -PUID=${PUID}\\n\ -PGID=${PGID}\\n\ -EASYRSA=${EASYRSA}\\n\ -EASYRSA_OPENSSL=${EASYRSA_OPENSSL}\\n\ -EASYRSA_SSL_CONF=${EASYRSA_SSL_CONF}\\n\ -EASYRSA_PKI=${EASYRSA_PKI}\\n\ -EASYRSA_DN=${EASYRSA_DN}\\n\ -EASYRSA_REQ_COUNTRY=${EASYRSA_REQ_COUNTRY}\\n\ -EASYRSA_REQ_PROVINCE=${EASYRSA_REQ_PROVINCE}\\n\ -EASYRSA_REQ_CITY=${EASYRSA_REQ_CITY}\\n\ -EASYRSA_REQ_ORG=${EASYRSA_REQ_ORG}\\n\ -EASYRSA_REQ_EMAIL=${EASYRSA_REQ_EMAIL}\\n\ -EASYRSA_REQ_OU=${EASYRSA_REQ_OU}\\n\ -EASYRSA_KEY_SIZE=${EASYRSA_KEY_SIZE}\\n\ -EASYRSA_ALGO=${EASYRSA_ALGO}\\n\ -EASYRSA_CURVE=${EASYRSA_CURVE}\\n\ -EASYRSA_EC_DIR=${EASYRSA_EC_DIR}\\n\ -EASYRSA_CA_EXPIRE=${EASYRSA_CA_EXPIRE}\\n\ -EASYRSA_CERT_EXPIRE=${EASYRSA_CERT_EXPIRE}\\n\ -EASYRSA_CRL_DAYS=${EASYRSA_CRL_DAYS}\\n\ -EASYRSA_NS_SUPPORT=${EASYRSA_NS_SUPPORT}\\n\ -EASYRSA_NS_COMMENT=${EASYRSA_NS_COMMENT}\\n\ -EASYRSA_TEMP_FILE=${EASYRSA_TEMP_FILE}\\n\ -EASYRSA_REQ_CN=${EASYRSA_REQ_CN}\\n\ -EASYRSA_DIGEST=${EASYRSA_DIGEST}\\n\ -EASYRSA_BATCH=${EASYRSA_BATCH}\\n\ -OVPN_PERINT=${OVPN_PERINT}\\n\ -" diff --git a/root/etc/cont-init.d/50-config b/root/etc/cont-init.d/50-config deleted file mode 100644 index abb8d48..0000000 --- a/root/etc/cont-init.d/50-config +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/with-contenv bash - -# File which indicates that full init was already done before -FLAG_FILE=/config/donotdelete - -HOOKS_DIR=(auth client-connect client-disconnect finish down init learn-address route-pre-down route-up up tls-verify) -OVPN_DIR=(ccd client server) - -FIRST_SETUP=0 - -# Check if we need initial setup -if [ ! -e "$FLAG_FILE" ]; then - FIRST_SETUP=1 - - # Full setup is required - touch $FLAG_FILE - - # Copy defaults to config (if not exist) - echo "Copying defaults" - cp -R -u /defaults/* /config -fi - -# Setup log -if [ ! -e "/config/log" ]; then - echo "Creating /config/log" - mkdir -p /config/log - touch /config/log/openvpn.log -fi - -# Setup hooks -if [ ! -e "/config/hooks" ]; then - echo "Creating /config/hooks" - mkdir -p /config/hooks -fi -# Check for each hook if exists -for h in "${HOOKS_DIR[@]}"; do - if [ ! -e "/config/hooks/$h" ]; then - echo "Creating /config/hooks/$h" - mkdir /config/hooks/$h - fi -done - -# Setup openvpn -if [ ! -e "/config/openvpn" ]; then - echo "Creating /config/openvpn" - mkdir -p /config/openvpn -fi -# Check for each dir if exists -for h in ${OVPN_DIR[@]} -do - if [ ! -e "/config/openvpn/$h" ]; then - echo "Creating /config/openvpn/$h" - mkdir /config/openvpn/$h - fi -done - -# Setup easy-rsa -if [ ! -e "/config/ssl" ]; then - echo "Setting up /config/ssl" - mkdir -p /config/ssl - #cp -R -u $EASYRSA/openssl-easyrsa.cnf $EASYRSA_SSL_CONF - cp -R -u $EASYRSA/vars.example /config/ssl/vars -else - #if [ ! -e "$EASYRSA_SSL_CONF" ]; then - # cp -R -u $EASYRSA/openssl-easyrsa.cnf $EASYRSA_SSL_CONF - #fi - if [ ! -e "/config/ssl/vars" ]; then - cp -R -u $EASYRSA/vars.example /config/ssl/vars - fi -fi -if [ -e "/config/pki" ]; then - # Create CRL file, if it can - if [ ! -e "/config/pki/crl.pem" ]; then - touch /config/pki/crl.pem - fi -fi - -# Setup module -if [ ! -e "/config/module" ]; then - echo "Creating /config/module" - mkdir /config/module -fi - -# Setup backup -if [ ! -e "/config/backup" ]; then - mkdir /config/backup -fi - -# Setup tmp -if [ ! -e "/config/tmp" ]; then - mkdir /config/tmp -fi - -# Build include-server.conf -INC_SERVER_FILE=/config/include-server.conf -echo "#" > $INC_SERVER_FILE -echo "# DO NOT EDIT" >> $INC_SERVER_FILE -echo "# Autogenerated file, based on /config/openvpn/server" >> $INC_SERVER_FILE -echo "#" >> $INC_SERVER_FILE -echo "" >> $INC_SERVER_FILE - -for file in /config/openvpn/server/*.conf -do - [ -e "$file" ] || continue - - echo "config $file" >> $INC_SERVER_FILE -done - -# Change permissions only on initial setup -if [ $FIRST_SETUP -eq 1 ]; then - echo "Fixing permissions" - - # Set permissions - chown -R abc:abc /config -fi \ No newline at end of file diff --git a/root/etc/cont-init.d/50-setup.sh b/root/etc/cont-init.d/50-setup.sh new file mode 100644 index 0000000..820f02f --- /dev/null +++ b/root/etc/cont-init.d/50-setup.sh @@ -0,0 +1,83 @@ +#!/usr/bin/with-contenv bash + +# +# Setup /config directory +# + +# Setup backup +if [ ! -e "/config/backup" ]; then + mkdir /config/backup + chown abc:abc /config/backup +fi + +# +# Setup openvpn directory +# + +if [ ! -d "/config/openvpn" ]; then + echo "Creating /config/openvpn" + mkdir -p /config/openvpn + chown abc:abc /config/openvpn +fi + +# Check directories inside openvpn directory +OVPN_DIR=(ccd client config hooks) +for h in ${OVPN_DIR[@]} +do + if [ ! -d "/config/openvpn/$h" ]; then + echo "Creating /config/openvpn/$h" + mkdir /config/openvpn/$h + chown abc:abc /config/openvpn/$h + fi +done + +# Check hook directories +HOOKS_DIR=( \ + auth \ + client-connect \ + client-disconnect \ + down \ + finish \ + init \ + learn-address \ + route-pre-down \ + route-up \ + tls-verify \ + up \ + ) +for h in "${HOOKS_DIR[@]}"; do + if [ ! -d "/config/openvpn/hooks/$h" ]; then + echo "Creating /config/openvpn/hooks/$h" + mkdir /config/openvpn/hooks/$h + chown abc:abc /config/openvpn/hooks/$h + fi +done + +# +# Setup EasyRSA +# + +if [ -d "/config/pki" ]; then + # Create CRL file, if it can + if [ ! -f "/config/pki/crl.pem" ]; then + touch /config/pki/crl.pem + fi +fi + +if [ ! -d "/config/ssl" ]; then + echo "Setting up /config/ssl" + mkdir -p /config/ssl + chown abc:abc /config/ssl +fi + +if [ ! -e "$EASYRSA_VARS_FILE" ]; then + #cp -R -u $EASYRSA/openssl-easyrsa.cnf $EASYRSA_SSL_CONF + cp -R -u $EASYRSA/vars.example $EASYRSA_VARS_FILE + chown abc:abc $EASYRSA_VARS_FILE +fi + +# Setup tmp +if [ ! -e "/config/tmp" ]; then + mkdir /config/tmp + chown abc:abc /config/tmp +fi diff --git a/root/etc/cont-init.d/60-network b/root/etc/cont-init.d/60-network deleted file mode 100644 index c435056..0000000 --- a/root/etc/cont-init.d/60-network +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/with-contenv bash - -source /app/lib/settings - -# -# Network setup -# - -# -# Setup tunnel driver -# -# @see https://help.skysilk.com/support/solutions/articles/9000136471-how-to-enable-tun-tap-on-linux-vps-with-skysilk -# @see https://community.openvpn.net/openvpn/wiki/UnprivilegedUser -# @see https://unix.stackexchange.com/questions/18215/which-user-group-can-use-the-tap-net-device -# -if [ ! -d "/dev/net" ]; then - echo "Creating /dev/net" - mkdir -p /dev/net -fi -if [ ! -c "/dev/net/tun" ]; then - mknod /dev/net/tun c 10 200 - chmod 666 /dev/net/tun -fi - -# Setup tun0 as tunnel interface -intTunExists -TUNE=$? -intPersistant -PERINT=$? -if [ $TUNE -eq 0 ] && [ $PERINT -eq 0 ]; then # TUN interface exists & !persistant - echo "Removing tun0 interface" - openvpn --rmtun --dev tun0 -fi -if [ $TUNE -eq 1 ]; then # TUN interface !exist - echo "Creating tun0 interface" - openvpn --mktun --dev tun0 --dev-type tun --user abc --group abc -fi \ No newline at end of file diff --git a/root/etc/cont-init.d/60-network.sh b/root/etc/cont-init.d/60-network.sh new file mode 100644 index 0000000..5a877a0 --- /dev/null +++ b/root/etc/cont-init.d/60-network.sh @@ -0,0 +1,31 @@ +#!/usr/bin/with-contenv bash + +# +# Setup tunnel driver +# +# @see https://help.skysilk.com/support/solutions/articles/9000136471-how-to-enable-tun-tap-on-linux-vps-with-skysilk +# @see https://community.openvpn.net/openvpn/wiki/UnprivilegedUser +# @see https://unix.stackexchange.com/questions/18215/which-user-group-can-use-the-tap-net-device +# + +if [ ! -d "/dev/net" ]; then + echo "Creating /dev/net" + mkdir -p /dev/net +fi + +if [ ! -c "/dev/net/tun" ]; then + mknod /dev/net/tun c 10 200 + chmod 666 /dev/net/tun +fi + +# Remove existing interface if not persistent interface selected +if [ -n "$(cat /proc/net/dev | grep tun0)" ] && { [ -z "$PERSISTENT_INTERFACE" ] || [ "$PERSISTENT_INTERFACE" != "true" ]; }; then + echo "Removing tun0 interface" + openvpn --rmtun --dev tun0 +fi + +# Create tunnel interface +if [ -n "$(cat /proc/net/dev | grep tun0)" ]; then + echo "Creating tun0 interface" + openvpn --mktun --dev tun0 --dev-type tun --user abc --group abc +fi diff --git a/root/etc/cont-init.d/70-config.sh b/root/etc/cont-init.d/70-config.sh new file mode 100644 index 0000000..acd078d --- /dev/null +++ b/root/etc/cont-init.d/70-config.sh @@ -0,0 +1,23 @@ +#!/usr/bin/with-contenv bash + +# +# Link OpenVPN configs +# + +LINK_FILE=/config/openvpn/include-conf.conf + +# Build link file +echo "#" > $LINK_FILE +echo "# DO NOT EDIT" >> $LINK_FILE +echo "# Autogenerated file, based on /config/openvpn/config" >> $LINK_FILE +echo "#" >> $LINK_FILE +echo "" >> $LINK_FILE + +for file in /config/openvpn/config/* +do + [ -e "$file" ] || continue + + echo "config $file" >> $LINK_FILE +done + +chown abc:abc $LINK_FILE diff --git a/root/etc/cont-init.d/99-custom_init b/root/etc/cont-init.d/99-custom_init.sh similarity index 100% rename from root/etc/cont-init.d/99-custom_init rename to root/etc/cont-init.d/99-custom_init.sh diff --git a/root/etc/logrotate.d/openvpn b/root/etc/logrotate.d/openvpn deleted file mode 100644 index 61c721f..0000000 --- a/root/etc/logrotate.d/openvpn +++ /dev/null @@ -1,9 +0,0 @@ -/config/log/openvpn.log { - weekly - rotate 7 - missingok - compress - delaycompress - nodateext - su abc abc -} \ No newline at end of file diff --git a/root/etc/services.d/openvpn/finish b/root/etc/services.d/openvpn/finish new file mode 100644 index 0000000..4134391 --- /dev/null +++ b/root/etc/services.d/openvpn/finish @@ -0,0 +1,9 @@ +#!/usr/bin/with-contenv sh + +# +# Handle service failiure +# + +if [ "$FAIL_MODE" == "hard" ]; then + exec s6-svscanctl -t /var/run/s6/services +fi diff --git a/root/etc/services.d/openvpn/run b/root/etc/services.d/openvpn/run index 12834ea..e3798f1 100644 --- a/root/etc/services.d/openvpn/run +++ b/root/etc/services.d/openvpn/run @@ -1,17 +1,31 @@ #!/usr/bin/with-contenv bash -CONFIGS=$(ls -1 /config/openvpn/server | wc -l) # Get number of files in /config/openvpn/server +if [ ! -d "/config/openvpn " ] || [ ! -f "/config/openvpn/system.conf" ]; then + echo "System configuration is missing" + if [ "$FAIL_MODE" != "hard" ]; then + # Do nothing until container restart + while true + do + sleep 3600 + done + fi + exit 1 +fi + +CONFIGS=$(ls -1 /config/openvpn/config | wc -l) # Get number of files if [ $CONFIGS -gt 0 ]; then - # Run OpenVPN server only if configs are present - echo "Running OpenVPN ..." - sudo -E -u abc openvpn --cd /config --config ${OVPN_RUN} + # Run OpenVPN only if configs are present + echo "Running OpenVPN ..." + sudo -E -u abc openvpn --config /config/openvpn/system.conf else - # No OpenVPN config present - echo "No OpenVPN config present" - + # No OpenVPN config present + echo "No OpenVPN config present" + if [ "$FAIL_MODE" != "hard" ]; then # Do nothing until container restart while true do - sleep 3600 + sleep 3600 done + fi + exit 1 fi \ No newline at end of file diff --git a/root/usr/local/bin/ovpn b/root/usr/local/bin/ovpn new file mode 100755 index 0000000..3dd8792 --- /dev/null +++ b/root/usr/local/bin/ovpn @@ -0,0 +1,41 @@ +#!/bin/bash + +# +# OpenVPN utils +# + +function usage() { + echo "Usage: ovpn COMMAND [ARGS..]" + echo "" + echo "Commands:" + echo " backup # Creates backup of configuration files" + echo " client [add|ovpn|ovpnp|ban|revoke|remove|delete|help] [NAME] [nopass] # Client manipulation" + echo " disconf # Deletes active config" + echo " enconf EXAMPLE_CONFIG_NAME [wizard args] # Enable example config" + echo " pki [init|remove|delete] # Public Key Intrastructure" + echo " restore ARCHIVE_FILE # Restores backup" +} + +if [ $# -lt 1 ] || [ "$1" == "help" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then + usage + exit 1 +fi + +# Run selected command +cmd="$(echo $1 | tr '[:upper:]' '[:lower:]')" # Convert to lowercase +if [ "$cmd" == "backup" ]; then + ovpn_backup ${@:2} +elif [ "$cmd" == "client" ]; then + ovpn_client ${@:2} +elif [ "$cmd" == "disconf" ]; then + ovpn_disconf ${@:2} +elif [ "$cmd" == "enconf" ]; then + ovpn_enconf ${@:2} +elif [ "$cmd" == "pki" ]; then + ovpn_pki ${@:2} +elif [ "$cmd" == "restore"]; then + ovpn_restore ${@:2} +else + usage + exit 1 +fi \ No newline at end of file diff --git a/root/usr/local/bin/ovpn_backup b/root/usr/local/bin/ovpn_backup new file mode 100755 index 0000000..bfb7e0a --- /dev/null +++ b/root/usr/local/bin/ovpn_backup @@ -0,0 +1,15 @@ +#!/bin/bash + +# +# Backup script +# +# Backups to /config/backup +# + +BACKUP_DIRS=(openvpn pki ssl) +ARCHIVE_NAME="/config/backup/ovpn_backup_$(date +%Y%m%d%H%M%S).tar.gz" + +cd /config && tar cfvz $ARCHIVE_NAME ${BACKUP_DIRS[@]} +if [ "$USER" != "abc" ]; then + chown abc:abc $ARCHIVE_NAME # Fix backup archive permissions +fi \ No newline at end of file diff --git a/root/usr/local/bin/ovpn_client b/root/usr/local/bin/ovpn_client new file mode 100755 index 0000000..c9d2eb4 --- /dev/null +++ b/root/usr/local/bin/ovpn_client @@ -0,0 +1,156 @@ +#!/bin/bash + +# +# OpenVPN client configuration generator +# + +# User permission fix +if [ "$USER" != "abc" ]; then + RUNAS="sudo -E -u abc" +else + RUNAS="" +fi + +function usage() { + echo "Usage: ovpn_client COMMAND [ARGS]" + echo "" + echo "Commands:" + echo " add [NAME [nopass]] # Creates certificates for client" + echo " ovpn NAME # Generates .ovpn file (saves to tmp)" + echo " ovpnp NAME # Generates .ovpn file (prints it to the screen)" + echo " revoke|ban NAME # Adds client to CRL" + echo " remove|delete NAME # Removes client config" +} + +# Invalid command / help +if [ $# -lt 1 ] || [ "$1" == "help" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then + usage + exit 1 +fi + +function build_ovpn() { + if [ $# -lt 1 ]; then + return 1 + fi + + local OVPN_FILE="/config/tmp/$1.ovpn" + + # Delete existing + if [ -f "$OVPN_FILE" ]; then + read -p ".ovpn file already exsist for $1, are you sure to overwrite it? [y/N]" decision + decision="$(echo $decision | tr '[:upper:]' '[:lower:]')" # Convert to lowercase + if [ "$decision" != "y" ] && [ "$decision" == "yes" ]; then + exit 0 # Don't overwrite + fi + rm $OVPN_FILE + fi + + # Build .ovpn from client config files + for file in /config/openvpn/client/*.conf + do + [ -e "$file" ] || continue + cat $file >> $OVPN_FILE + done + + # Find which security mechanism is openvpn using + local crypto="" + for srv_file in /config/openvpn/config/*.conf + do + crypto=`cat $srv_file | grep -E "^\\s*(secret|tls-auth|tls-crypt).*$" | cut -d" " -f1` + if [ -n "$crypto" ]; then + break + fi + done + + # Add ca.crt + echo "" >> $OVPN_FILE + cat $EASYRSA_PKI/ca.crt >> $OVPN_FILE + echo "" >> $OVPN_FILE + echo "" >> $OVPN_FILE + + # Add client cert + echo "" >> $OVPN_FILE + cat $EASYRSA_PKI/issued/$1.crt >> $OVPN_FILE + echo "" >> $OVPN_FILE + + # Add client key + echo "" >> $OVPN_FILE + cat $EASYRSA_PKI/private/$1.key >> $OVPN_FILE + echo "" >> $OVPN_FILE + + # Add security mechanism specific key + if [ "$crypto" == "tls-crypt" ]; then + echo "" >> $OVPN_FILE + cat $EASYRSA_PKI/ta.key >> $OVPN_FILE + echo "" >> $OVPN_FILE + elif [ "$crypto" == "tls-auth" ]; then + echo "" >> $OVPN_FILE + cat $EASYRSA_PKI/ta.key >> $OVPN_FILE + echo "" >> $OVPN_FILE + elif [ "$crypto" == "secret" ]; then + echo "" >> $OVPN_FILE + cat $EASYRSA_PKI/secret.key >> $OVPN_FILE + echo "" >> $OVPN_FILE + fi + + chown abc:abc $OVPN_FILE + + if [ $# -gt 1 ] && [ "$2" == "print" ]; then + cat $OVPN_FILE + fi +} + +if [ "$1" == "add" ]; then + if [ $# -eq 1 ]; then # No additional args + read -p "Common name:" commonName + read -p "Password protect [Y/n]: " decision + decision="$(echo $decision | tr '[:upper:]' '[:lower:]')" # Convert to lowercase + if [ "$decision" == "n" ] || [ "$decision" == "no" ]; then + $RUNAS easyrsa gen-req $commonName nopass + else + $RUNAS easyrsa gen-req $commonName + fi + $RUNAS easyrsa sign-req client $commonName + else + # Just build cert + $RUNAS easyrsa gen-req ${@:2} + $RUNAS easyrsa sign-req client ${@:2} + fi +elif [ "$1" == "ovpn" ]; then + if [ $# -gt 1 ]; then + build_ovpn $2 + else # Common name missing + usage + exit 1 + fi +elif [ "$1" == "ovpnp" ]; then + if [ $# -gt 1 ]; then + build_ovpn $2 print + else # Common name missing + usage + exit 1 + fi +elif [ "$1" = "ban" ] || [ "$1" = "revoke" ] ; then + if [ $# -gt 1 ]; then + $RUNAS easyrsa revoke ${@:2} + $RUNAS easyrsa gen-crl + else + usage + exit 1 + fi +elif [ "$1" = "remove" ] || [ "$1" = "delete"]; then + if [ $# -gt 1 ]; then + read -p "Are you sure to remove certs for $2 ? [y/N]: " decision + decision="$(echo $decision | tr '[:upper:]' '[:lower:]')" # Convert to lowercase + if [ "$decision" == "y" ] || [ "$decision" == "yes" ]; then + rm $EASYRSA_PKI/issued/$1.crt + rm $EASYRSA_PKI/private/$1.key + fi + else + usage + exit 1 + fi +else + usage + exit 1 +fi diff --git a/root/usr/local/bin/ovpn_disconf b/root/usr/local/bin/ovpn_disconf new file mode 100755 index 0000000..c37c75d --- /dev/null +++ b/root/usr/local/bin/ovpn_disconf @@ -0,0 +1,40 @@ +#!/bin/bash + +# +# Disables OpenVPN config +# WARNING: This deletes active OpenVPN config & active hooks +# + +# Check if OpenVPN config directory exsist +config_path="/config/openvpn" +if [ ! -d "$config_path" ]; then + exit 0 +fi + +# Display notice +echo "This script will clear your configuration (whole openvpn directory)." +echo "Please make sure that you backed up you config and active hooks." + +# Make sure that user understands +read -p "Are you sure, you want to delete active config and hooks ? [y/N]:" decision +decision="$(echo $decision | tr '[:upper:]' '[:lower:]')" # Convert to lowercase + +# Check if operation aborted +if [ "$decision" != "y" ] && [ "$decision" != "yes" ]; then + exit 0 +fi + +# Delete config +if [ -d "$config_path/config" ]; then + rm -rf $config_path/config/* +fi + +# Delete client config +if [ -d "$config_path/client" ]; then + rm -rf $config_path/client/* +fi + +# Delete hook scripts +if [ -d "$config_path/hooks" ]; then + rm -rf $config_path/hooks/*/* +fi diff --git a/root/usr/local/bin/ovpn_enconf b/root/usr/local/bin/ovpn_enconf new file mode 100755 index 0000000..e03bea7 --- /dev/null +++ b/root/usr/local/bin/ovpn_enconf @@ -0,0 +1,109 @@ +#!/bin/bash + +# +# Enables OpenVPN config example +# + +# User permission fix +if [ "$USER" != "abc" ]; then + RUNAS="sudo -E -u abc" +else + RUNAS="" +fi + +function usage() { + echo "Usage: ovpn_enconf CONFIG_NAME [wizard args...]" + echo "" + echo "Configs:" + local identifiers=() # Which identifiers we already printed out + + # Go through all identifiers + for folder in /defaults/example/config/* + do + [ -d "$folder" ] || continue + + local folder_name="$(echo $folder | sed -E 's/^\/.*\/(.*)$/\1/')" + + # Check if we already printed out that identifer + local found=0 + for i in "$identifiers" + do + if [ "$i" = "$folder_name" ]; then + found=1 + break + fi + done + if [ $found -eq 0 ]; then + # Print out new identifier + echo "$folder_name" + identifiers=($identifiers $folder_name) + fi + done +} + +if [ $# -lt 1 ] || [ "$1" == "help" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then + usage + exit 1 +fi + +# Get wanted config name +config_name=$1 +config_path=/defaults/example/config/$config_name + +# Check if config exists +if [ ! -d $config_path ]; then + echo "Config does not exist" + exit 2 +fi + + +# Configure copy destination +if [ -f "$config_path/wizard" ] && [ -x "$config_path/wizard" ]; then + tmp_path=/tmp/wizard + + # Delete existing tmp directory + if [ -d "$tmp_path" ]; then + rm -rf $tmp_path + fi + + # Copy config to temporary folder so it can be modified + $RUNAS cp -r $config_path $tmp_path + + # Run wizard (with temporary path) + currdir="$(pwd)" + cd $tmp_path + $RUNAS $tmp_path/wizard "$tmp_path" ${@:2} + exit_code=$? + cd $currdir + + # If wizard exists with code other than 0, return error + if [ $exit_code -ne 0 ]; then + echo "Error while executing wizard" + exit $exit_code + fi + + # Copy wizard finished files + COPY_DIRS=(ccd client config hooks) + for dir in "${COPY_DIRS[@]}" + do + [ -d "$tmp_path/$dir" ] || continue + $RUNAS cp -r $tmp_path/$dir/* /config/openvpn/$dir/ + done + + # Remove temporary directory + rm -rf $tmp_path +else + # Directly copy files + # Copy wizard finished files + COPY_DIRS=(ccd client config hooks) + for dir in "${COPY_DIRS[@]}" + do + [ -d "$config_path/$dir" ] || continue + $RUNAS cp -r $config_path/$dir/* /config/openvpn/$dir/ + done + + # Wizard not available + echo "Sorry, wizard not available for this config" + echo "" + echo "Please edit config files in /config/openvpn to suite your needs" +fi diff --git a/root/usr/local/bin/ovpn_pki b/root/usr/local/bin/ovpn_pki new file mode 100755 index 0000000..ca4acd9 --- /dev/null +++ b/root/usr/local/bin/ovpn_pki @@ -0,0 +1,86 @@ +#!/bin/bash + +# +# OpenVPN PKI configuration script +# +# @see https://community.openvpn.net/openvpn/wiki/EasyRSA3-OpenVPN-Howto +# @see https://forums.openvpn.net/viewtopic.php?t=20837 +# @see https://securitronlinux.com/bejiitaswrath/how-to-create-keys-with-easy-rsa-without-a-password-prompt/ +# +# + +# User permission fix +if [ "$USER" != "abc" ]; then + RUNAS="sudo -E -u abc" +else + RUNAS="" +fi + +function usage() { + echo "Usage: ovpn_pki COMMAND" + echo "" + echo "Commands:" + echo " delete|remove # Removes PKI" + echo " init [nopass] # Init PKI" +} + +if [ $# -lt 1 ] || [ "$1" == "help" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then + usage + exit 1 +fi + + +# +# Init CA +# +function init() { + if [ -d "$EASYRSA_PKI" ]; then + read -p "PKI directory already exists. You will LOSE all files in your PKI. Are you SURE to init PKI again ? [y/N]: " decission + decision="$(echo $decision | tr '[:upper:]' '[:lower:]')" # Convert to lowercase + if [ "$decision" != "y"] && [ "$decision" != "yes" ]; then + exit 0 + fi + rm -rf $EASYRSA_PKI + fi + + # Init PKI + $RUNAS easyrsa init-pki + + # Build dh.pem + $RUNAS easyrsa gen-dh + + # Build CA + echo "Now it will build CA files for issuing new certifiactes" + echo "Please protect ca.key with secure password (used for signing new certs)" + echo "ca.key is needed only for signing new certificates, not for OpenVPN to work" + $RUNAS easyrsa build-ca ${@:1} + + # Build server key + $RUNAS easyrsa build-server-full server nopass + $RUNAS easyrsa sign-req server server + rm $EASYRSA_PKI/reqs/server.req + + # Generate ta.key (for tls-auth,tls-crypt) + $RUNAS openvpn --genkey --secret $EASYRSA_PKI/ta.key + + # Generate CRL + $RUNAS easyrsa gen-crl +} + +cmd="$(echo $1 | tr '[:upper:]' '[:lower:]')" +if [ "$cmd" == "init" ]; then + init ${@:2} +elif [ "$cmd" == "remove"] || [ "$cmd" == "delete" ]; then + if [ ! -d "$EASYRSA_PKI" ]; then + exit 0 + fi + read -p "Are you sure to remove PKI ? [y/N]: " decision + decision="$(echo $decision | tr '[:upper:]' '[:lower:]')" # Convert to lowercase + # Check if operation aborted + if [ "$decision" == "y" ] && [ "$decision" == "yes" ]; then + rm -rf $EASYRSA_PKI + fi +else + usage + exit 1 +fi diff --git a/root/usr/local/bin/ovpn_restore b/root/usr/local/bin/ovpn_restore new file mode 100644 index 0000000..4445c94 --- /dev/null +++ b/root/usr/local/bin/ovpn_restore @@ -0,0 +1,24 @@ +#!/bin/bash + +# +# Restore script +# +# Restores config from archive +# + +# User permission fix +if [ "$USER" != "abc" ]; then + RUNAS="sudo -E -u abc" +else + RUNAS="" +fi + +read -p "Make sure to disable current config (ovpn disconf) and remove current pki (ovpn pki remove), before you restore config. Done ? [Y/n]: " decision +decision="$(echo $decision | tr '[:upper:]' '[:lower:]')" # Convert to lowercase + +# Check if operation aborted +if [ "$decision" == "n" ] && [ "$decision" == "no" ]; then + exit 0 +fi + +$RUNAS tar -fvx $1 -C /config diff --git a/root/usr/local/bin/run_hooks b/root/usr/local/bin/run_hooks new file mode 100755 index 0000000..460b67a --- /dev/null +++ b/root/usr/local/bin/run_hooks @@ -0,0 +1,52 @@ +#!/bin/bash + +# +# Run hook scripts +# + +function usage() { + echo "Usage: run_hooks HOOK_NAME [ARGS]" + echo "" + echo "Hooks:" + echo " auth On OpenVPN client authentication" + echo " client-connect On OpenVPN client connected" + echo " client-disconnect On OpenVPN client disconnected" + echo " finish On container shutdown" + echo " init On container power on" + echo " learn-address Client Address & Routes validation" + echo " down Before/After TUN interface closed" + echo " route-up After routes are added" + echo " route-pre-down Before routes are removed" + echo " tls-verify On OpenVPN client certificate verificaton" + echo " up After TUN interface opened" +} + +# Check if hook name is set +if [ -z "$1" ]; then + usage + exit 1 +fi + +# Check if hook directory exist +if [ ! -d "/config/openvpn/hooks/$1" ]; then + echo "Hook /config/openvpn/hooks/$1 directory does not exist" + exit 2 +fi + +# Run each script and check for return code +for script in /config/openvpn/hooks/$1/* +do + { [ -f "$script" ] && [ -x "$script" ]; } || continue + + # Run script and pass additional args to hooks + echo "Executing hook: $script" + $script ${@:2} + + # Check for error while executing script + exit_status=$? + if [ $exit_status -ne 0 ]; then + # In case one of the hook files fails, everything fails + echo "$script exited with $exit_status." + exit $exit_status + fi +done From 6a49a2f5cf9bab541884799da15ff4a7170df76b Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 00:23:18 +0200 Subject: [PATCH 03/14] Removed old img links --- README.md | 2 -- docker-compose.yml | 2 -- 2 files changed, 4 deletions(-) diff --git a/README.md b/README.md index a23a05a..d94c928 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,6 @@ services: # If you want to build from source add build: build: context: . - cache_from: - - lsiobase/alpine.python3:latest sysctls: # For IPv6 - net.ipv6.conf.all.disable_ipv6=0 - net.ipv6.conf.default.forwarding=1 diff --git a/docker-compose.yml b/docker-compose.yml index fb4a968..4709628 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,8 +20,6 @@ services: restart: on-failure build: context: . - cache_from: - - lsiobase/alpine.python3:latest sysctls: # For IPv6 - net.ipv6.conf.all.disable_ipv6=0 - net.ipv6.conf.default.forwarding=1 From b4ee7588d2f89af983cac8296d8da02cf7714924 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 14:17:32 +0200 Subject: [PATCH 04/14] Added exec permission, fixed outdated docs --- root/defaults/example/README.md | 2 +- root/etc/cont-finish.d/99-custom_finish.sh | 0 root/etc/cont-init.d/50-setup.sh | 0 root/etc/cont-init.d/60-network.sh | 0 root/etc/cont-init.d/70-config.sh | 0 root/etc/cont-init.d/99-custom_init.sh | 0 root/usr/local/bin/ovpn_restore | 0 7 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 root/etc/cont-finish.d/99-custom_finish.sh mode change 100644 => 100755 root/etc/cont-init.d/50-setup.sh mode change 100644 => 100755 root/etc/cont-init.d/60-network.sh mode change 100644 => 100755 root/etc/cont-init.d/70-config.sh mode change 100644 => 100755 root/etc/cont-init.d/99-custom_init.sh mode change 100644 => 100755 root/usr/local/bin/ovpn_restore diff --git a/root/defaults/example/README.md b/root/defaults/example/README.md index 1255f25..f8a5f86 100644 --- a/root/defaults/example/README.md +++ b/root/defaults/example/README.md @@ -26,7 +26,7 @@ config # Directory with your examples client # Directory, OpenVPN client config files .conf # Partial OpenVPN client config file - server # Directory, OpenVPN server config files + config # Directory, OpenVPN server config files .conf # Partial OpenVPN server config file hooks # Directory with hooks for this example # Directory, name of hook diff --git a/root/etc/cont-finish.d/99-custom_finish.sh b/root/etc/cont-finish.d/99-custom_finish.sh old mode 100644 new mode 100755 diff --git a/root/etc/cont-init.d/50-setup.sh b/root/etc/cont-init.d/50-setup.sh old mode 100644 new mode 100755 diff --git a/root/etc/cont-init.d/60-network.sh b/root/etc/cont-init.d/60-network.sh old mode 100644 new mode 100755 diff --git a/root/etc/cont-init.d/70-config.sh b/root/etc/cont-init.d/70-config.sh old mode 100644 new mode 100755 diff --git a/root/etc/cont-init.d/99-custom_init.sh b/root/etc/cont-init.d/99-custom_init.sh old mode 100644 new mode 100755 diff --git a/root/usr/local/bin/ovpn_restore b/root/usr/local/bin/ovpn_restore old mode 100644 new mode 100755 From bec394a5c018c637c70d30689dad64bbaccb5891 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 14:27:26 +0200 Subject: [PATCH 05/14] Fixed fw hooks pre-checks --- root/app/hookBaseFirewallDestroy.sh | 15 +++++++++++++++ ...okBaseFirewall.sh => hookBaseFirewallSetup.sh} | 14 +++++++------- .../config/basic_nat/hooks/down/10-network.sh | 2 +- .../config/basic_nat/hooks/finish/10-network.sh | 2 +- .../config/basic_nat/hooks/init/10-network.sh | 2 +- .../config/basic_nat/hooks/up/10-network.sh | 2 +- .../config/basic_nat_wlp/hooks/down/10-network.sh | 2 +- .../basic_nat_wlp/hooks/finish/10-network.sh | 2 +- .../config/basic_nat_wlp/hooks/init/10-network.sh | 2 +- .../config/basic_nat_wlp/hooks/up/10-network.sh | 2 +- .../config/basic_routed/hooks/down/10-network.sh | 2 +- .../basic_routed/hooks/finish/10-network.sh | 2 +- .../config/basic_routed/hooks/init/10-network.sh | 2 +- .../config/basic_routed/hooks/up/10-network.sh | 2 +- 14 files changed, 34 insertions(+), 19 deletions(-) create mode 100755 root/app/hookBaseFirewallDestroy.sh rename root/app/{hookBaseFirewall.sh => hookBaseFirewallSetup.sh} (61%) mode change 100644 => 100755 diff --git a/root/app/hookBaseFirewallDestroy.sh b/root/app/hookBaseFirewallDestroy.sh new file mode 100755 index 0000000..eaccf94 --- /dev/null +++ b/root/app/hookBaseFirewallDestroy.sh @@ -0,0 +1,15 @@ +#!/usr/bin/with-contenv bash + +# +# Pre-checks for firewall destruction related hooks +# + +# Check if firewall rules are disabled +if [ "$USE_FIREWALL" == "false" ]; then + exit 0 # Don't use fw rules +fi + +# Don't run if persistent interface +if [ "$PERSISTENT_INTERFACE" == "true" ]; then + exit 0 +fi diff --git a/root/app/hookBaseFirewall.sh b/root/app/hookBaseFirewallSetup.sh old mode 100644 new mode 100755 similarity index 61% rename from root/app/hookBaseFirewall.sh rename to root/app/hookBaseFirewallSetup.sh index 6418892..fa4266a --- a/root/app/hookBaseFirewall.sh +++ b/root/app/hookBaseFirewallSetup.sh @@ -1,20 +1,20 @@ #!/usr/bin/with-contenv bash # -# Pre-checks for firewall related hooks +# Pre-checks for firewall setup related hooks # # Check if firewall rules are disabled if [ "$USE_FIREWALL" == "false" ]; then - exit 0 # Don't use fw rules + exit 0 # Don't use fw rules fi # Run script only once if persistent interface # @see https://stackoverflow.com/questions/4774054/reliable-way-for-a-bash-script-to-get-the-full-path-to-itself if [ "$PERSISTENT_INTERFACE" == "true" ]; then - flagFile="$(realpath $0).flag" - if [ -f "$flagFile" ]; then - exit 0 # Flag file exists, exit - fi - touch $flagFile + flagFile="$(realpath $0).flag" + if [ -f "$flagFile" ]; then + exit 0 # Flag file exists, exit + fi + touch $flagFile fi \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat/hooks/down/10-network.sh b/root/defaults/example/config/basic_nat/hooks/down/10-network.sh index 23255ec..98a1414 100755 --- a/root/defaults/example/config/basic_nat/hooks/down/10-network.sh +++ b/root/defaults/example/config/basic_nat/hooks/down/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallDestroy.sh # # Network clear diff --git a/root/defaults/example/config/basic_nat/hooks/finish/10-network.sh b/root/defaults/example/config/basic_nat/hooks/finish/10-network.sh index dc6699b..9b2920f 100755 --- a/root/defaults/example/config/basic_nat/hooks/finish/10-network.sh +++ b/root/defaults/example/config/basic_nat/hooks/finish/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallDestroy.sh # # Network clear diff --git a/root/defaults/example/config/basic_nat/hooks/init/10-network.sh b/root/defaults/example/config/basic_nat/hooks/init/10-network.sh index e127050..c9e3c38 100755 --- a/root/defaults/example/config/basic_nat/hooks/init/10-network.sh +++ b/root/defaults/example/config/basic_nat/hooks/init/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallSetup.sh # # Network initialization diff --git a/root/defaults/example/config/basic_nat/hooks/up/10-network.sh b/root/defaults/example/config/basic_nat/hooks/up/10-network.sh index f170cc2..f551d8c 100755 --- a/root/defaults/example/config/basic_nat/hooks/up/10-network.sh +++ b/root/defaults/example/config/basic_nat/hooks/up/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallSetup.sh # # Network initialization diff --git a/root/defaults/example/config/basic_nat_wlp/hooks/down/10-network.sh b/root/defaults/example/config/basic_nat_wlp/hooks/down/10-network.sh index 6f61b5a..c52da9a 100755 --- a/root/defaults/example/config/basic_nat_wlp/hooks/down/10-network.sh +++ b/root/defaults/example/config/basic_nat_wlp/hooks/down/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallDestroy.sh # # Network clear diff --git a/root/defaults/example/config/basic_nat_wlp/hooks/finish/10-network.sh b/root/defaults/example/config/basic_nat_wlp/hooks/finish/10-network.sh index ab24e9f..db58c82 100755 --- a/root/defaults/example/config/basic_nat_wlp/hooks/finish/10-network.sh +++ b/root/defaults/example/config/basic_nat_wlp/hooks/finish/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallDestroy.sh # # Network clear diff --git a/root/defaults/example/config/basic_nat_wlp/hooks/init/10-network.sh b/root/defaults/example/config/basic_nat_wlp/hooks/init/10-network.sh index 0405102..7ae8a95 100755 --- a/root/defaults/example/config/basic_nat_wlp/hooks/init/10-network.sh +++ b/root/defaults/example/config/basic_nat_wlp/hooks/init/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallSetup.sh # # Network initialization diff --git a/root/defaults/example/config/basic_nat_wlp/hooks/up/10-network.sh b/root/defaults/example/config/basic_nat_wlp/hooks/up/10-network.sh index f5a92da..0f3b363 100755 --- a/root/defaults/example/config/basic_nat_wlp/hooks/up/10-network.sh +++ b/root/defaults/example/config/basic_nat_wlp/hooks/up/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallSetup.sh # # Network initialization diff --git a/root/defaults/example/config/basic_routed/hooks/down/10-network.sh b/root/defaults/example/config/basic_routed/hooks/down/10-network.sh index 181eab9..f389549 100755 --- a/root/defaults/example/config/basic_routed/hooks/down/10-network.sh +++ b/root/defaults/example/config/basic_routed/hooks/down/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallDestroy.sh # # Network clear diff --git a/root/defaults/example/config/basic_routed/hooks/finish/10-network.sh b/root/defaults/example/config/basic_routed/hooks/finish/10-network.sh index dc6699b..9b2920f 100755 --- a/root/defaults/example/config/basic_routed/hooks/finish/10-network.sh +++ b/root/defaults/example/config/basic_routed/hooks/finish/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallDestroy.sh # # Network clear diff --git a/root/defaults/example/config/basic_routed/hooks/init/10-network.sh b/root/defaults/example/config/basic_routed/hooks/init/10-network.sh index e127050..c9e3c38 100755 --- a/root/defaults/example/config/basic_routed/hooks/init/10-network.sh +++ b/root/defaults/example/config/basic_routed/hooks/init/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallSetup.sh # # Network initialization diff --git a/root/defaults/example/config/basic_routed/hooks/up/10-network.sh b/root/defaults/example/config/basic_routed/hooks/up/10-network.sh index 8a28d3c..485cef4 100755 --- a/root/defaults/example/config/basic_routed/hooks/up/10-network.sh +++ b/root/defaults/example/config/basic_routed/hooks/up/10-network.sh @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -source /app/hookBaseFirewall.sh +source /app/hookBaseFirewallSetup.sh # # Network initialization From c1b1442f0bf3e6ebc9836ba8e698789d4be74059 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 15:07:16 +0200 Subject: [PATCH 06/14] Removed old things --- Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8ae86a0..fde4921 100644 --- a/Dockerfile +++ b/Dockerfile @@ -87,6 +87,3 @@ RUN apk add --no-cache \ # Add repo files to image COPY root/ / - -# Configure -RUN chmod -R 0644 /etc/logrotate.d From 04fd8b8260467d3c6a8103c26fea282b2c8569cf Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 15:07:40 +0200 Subject: [PATCH 07/14] Fixed bugs --- root/etc/cont-init.d/60-network.sh | 2 +- root/etc/services.d/openvpn/run | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/root/etc/cont-init.d/60-network.sh b/root/etc/cont-init.d/60-network.sh index 5a877a0..37dcf20 100755 --- a/root/etc/cont-init.d/60-network.sh +++ b/root/etc/cont-init.d/60-network.sh @@ -25,7 +25,7 @@ if [ -n "$(cat /proc/net/dev | grep tun0)" ] && { [ -z "$PERSISTENT_INTERFACE" ] fi # Create tunnel interface -if [ -n "$(cat /proc/net/dev | grep tun0)" ]; then +if [ -z "$(cat /proc/net/dev | grep tun0)" ]; then echo "Creating tun0 interface" openvpn --mktun --dev tun0 --dev-type tun --user abc --group abc fi diff --git a/root/etc/services.d/openvpn/run b/root/etc/services.d/openvpn/run index e3798f1..3214e75 100644 --- a/root/etc/services.d/openvpn/run +++ b/root/etc/services.d/openvpn/run @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -if [ ! -d "/config/openvpn " ] || [ ! -f "/config/openvpn/system.conf" ]; then +if [ ! -d "/config/openvpn" ] || [ ! -f "/config/openvpn/system.conf" ]; then echo "System configuration is missing" if [ "$FAIL_MODE" != "hard" ]; then # Do nothing until container restart From e237a80c70194784de5c1ddd920219f8e2228269 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 15:20:31 +0200 Subject: [PATCH 08/14] Fixed paths --- .../example/config/basic_nat/config/server.conf | 12 ++++++------ .../config/basic_nat_wlp/config/server.conf | 12 ++++++------ .../config/basic_routed/config/server.conf | 12 ++++++------ root/defaults/openvpn/system.conf | 16 ++++++++-------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/root/defaults/example/config/basic_nat/config/server.conf b/root/defaults/example/config/basic_nat/config/server.conf index 52d786e..995bf6d 100644 --- a/root/defaults/example/config/basic_nat/config/server.conf +++ b/root/defaults/example/config/basic_nat/config/server.conf @@ -17,14 +17,14 @@ push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS $DNS1" push "dhcp-option DNS $DNS2" -ifconfig-pool-persist tmp/ipp.txt +ifconfig-pool-persist /config/tmp/ipp.txt # CA files -ca pki/ca.crt -cert pki/issued/server.crt -key pki/private/server.key -dh pki/dh.pem -tls-crypt pki/ta.key +ca /config/pki/ca.crt +cert /config/pki/issued/server.crt +key /config/pki/private/server.key +dh /config/pki/dh.pem +tls-crypt /config/pki/ta.key remote-cert-tls client # Connection settings diff --git a/root/defaults/example/config/basic_nat_wlp/config/server.conf b/root/defaults/example/config/basic_nat_wlp/config/server.conf index 52d786e..995bf6d 100644 --- a/root/defaults/example/config/basic_nat_wlp/config/server.conf +++ b/root/defaults/example/config/basic_nat_wlp/config/server.conf @@ -17,14 +17,14 @@ push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS $DNS1" push "dhcp-option DNS $DNS2" -ifconfig-pool-persist tmp/ipp.txt +ifconfig-pool-persist /config/tmp/ipp.txt # CA files -ca pki/ca.crt -cert pki/issued/server.crt -key pki/private/server.key -dh pki/dh.pem -tls-crypt pki/ta.key +ca /config/pki/ca.crt +cert /config/pki/issued/server.crt +key /config/pki/private/server.key +dh /config/pki/dh.pem +tls-crypt /config/pki/ta.key remote-cert-tls client # Connection settings diff --git a/root/defaults/example/config/basic_routed/config/server.conf b/root/defaults/example/config/basic_routed/config/server.conf index 52d786e..995bf6d 100644 --- a/root/defaults/example/config/basic_routed/config/server.conf +++ b/root/defaults/example/config/basic_routed/config/server.conf @@ -17,14 +17,14 @@ push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS $DNS1" push "dhcp-option DNS $DNS2" -ifconfig-pool-persist tmp/ipp.txt +ifconfig-pool-persist /config/tmp/ipp.txt # CA files -ca pki/ca.crt -cert pki/issued/server.crt -key pki/private/server.key -dh pki/dh.pem -tls-crypt pki/ta.key +ca /config/pki/ca.crt +cert /config/pki/issued/server.crt +key /config/pki/private/server.key +dh /config/pki/dh.pem +tls-crypt /config/pki/ta.key remote-cert-tls client # Connection settings diff --git a/root/defaults/openvpn/system.conf b/root/defaults/openvpn/system.conf index 3a2d557..3b1df6d 100644 --- a/root/defaults/openvpn/system.conf +++ b/root/defaults/openvpn/system.conf @@ -17,15 +17,15 @@ dev tun0 script-security 2 # Hooks call -route-up "run_hooks route-up" -route-pre-down "run_hooks route-pre-down" -up "run_hooks up" +route-up "/usr/local/bin/run_hooks route-up" +route-pre-down "/usr/local/bin/run_hooks route-pre-down" +up "/usr/local/bin/run_hooks up" down-pre -down "run_hooks down" -client-connect "run_hooks client-connect" -client-disconnect "run_hooks client-disconnect" -learn-address "run_hooks learn-address" -tls-verify "run_hooks tls-verify" +down "/usr/local/bin/run_hooks down" +client-connect "/usr/local/bin/run_hooks client-connect" +client-disconnect "/usr/local/bin/run_hooks client-disconnect" +learn-address "/usr/local/bin/run_hooks learn-address" +tls-verify "/usr/local/bin/run_hooks tls-verify" # # For username & password authentication uncomment bellow From ac05b41efbf593a3a0a8ce38ca2601512501a614 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 15:20:43 +0200 Subject: [PATCH 09/14] Less debuging --- root/defaults/openvpn/system.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/root/defaults/openvpn/system.conf b/root/defaults/openvpn/system.conf index 3b1df6d..701a65b 100644 --- a/root/defaults/openvpn/system.conf +++ b/root/defaults/openvpn/system.conf @@ -39,7 +39,7 @@ tls-verify "/usr/local/bin/run_hooks tls-verify" tmp-dir /config/tmp # Logging -verb 3 +verb 1 mute 100 #log-append /log/openvpn.log From 4be4c7b3fc633fe7239dcab20487598e0b8b2e54 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 15:40:19 +0200 Subject: [PATCH 10/14] Added example with client static options --- .../client_staticopts/ccd/clientCommonName | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 root/defaults/example/config/client_staticopts/ccd/clientCommonName diff --git a/root/defaults/example/config/client_staticopts/ccd/clientCommonName b/root/defaults/example/config/client_staticopts/ccd/clientCommonName new file mode 100644 index 0000000..eb62023 --- /dev/null +++ b/root/defaults/example/config/client_staticopts/ccd/clientCommonName @@ -0,0 +1,28 @@ +# +# Set static options for client +# @see https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage +# + +# Disable client (prevent from connecting, for security compromise REVOKE client) +# disable + +# Client Static IP +# ifconfig-push IP_ADDRESS MASK + +# Generate routes through this client when connects +# iroute NETWORK [NETMASK] + +# Don't inherit global push settings +# push-reset + +# Push option to client +# push OPTION + +# Remove option from client +# push-remove OPTION + +# Client Static IPv6 +# ifconfig-ipv6-push ADDRESS/CIDR REMOTE + +# Route through client +# iroute-ipv6 ADDRESS/CIDR \ No newline at end of file From eda3d80912f57bb11789ff5c1ef6bc42b61fce15 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 16:02:22 +0200 Subject: [PATCH 11/14] Removed unnessary option --- root/defaults/example/config/basic_nat/client/client.conf | 2 -- root/defaults/example/config/basic_nat_wlp/client/client.conf | 2 -- root/defaults/example/config/basic_routed/client/client.conf | 2 -- 3 files changed, 6 deletions(-) diff --git a/root/defaults/example/config/basic_nat/client/client.conf b/root/defaults/example/config/basic_nat/client/client.conf index 271ab49..5c956c7 100644 --- a/root/defaults/example/config/basic_nat/client/client.conf +++ b/root/defaults/example/config/basic_nat/client/client.conf @@ -10,8 +10,6 @@ client dev tun0 proto $PROTO nobind -pull - # Remote info remote $SERVER_IP $PORT diff --git a/root/defaults/example/config/basic_nat_wlp/client/client.conf b/root/defaults/example/config/basic_nat_wlp/client/client.conf index 271ab49..5c956c7 100644 --- a/root/defaults/example/config/basic_nat_wlp/client/client.conf +++ b/root/defaults/example/config/basic_nat_wlp/client/client.conf @@ -10,8 +10,6 @@ client dev tun0 proto $PROTO nobind -pull - # Remote info remote $SERVER_IP $PORT diff --git a/root/defaults/example/config/basic_routed/client/client.conf b/root/defaults/example/config/basic_routed/client/client.conf index 271ab49..5c956c7 100644 --- a/root/defaults/example/config/basic_routed/client/client.conf +++ b/root/defaults/example/config/basic_routed/client/client.conf @@ -10,8 +10,6 @@ client dev tun0 proto $PROTO nobind -pull - # Remote info remote $SERVER_IP $PORT From 2f133ec2beddb57d6cc75e89422bf783b736dda2 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 28 Jul 2019 21:49:46 +0200 Subject: [PATCH 12/14] Added IPv6 examples --- .../example/config/basic_nat_ipv6/README.md | 21 ++++ .../config/basic_nat_ipv6/client/client.conf | 34 +++++++ .../config/basic_nat_ipv6/config/server.conf | 46 +++++++++ .../basic_nat_ipv6/hooks/down/10-network.sh | 27 ++++++ .../basic_nat_ipv6/hooks/finish/10-network.sh | 24 +++++ .../basic_nat_ipv6/hooks/init/10-network.sh | 29 ++++++ .../basic_nat_ipv6/hooks/up/10-network.sh | 27 ++++++ .../example/config/basic_nat_ipv6/wizard | 95 +++++++++++++++++++ .../config/basic_nat_wlp_ipv6/README.md | 21 ++++ .../basic_nat_wlp_ipv6/client/client.conf | 34 +++++++ .../basic_nat_wlp_ipv6/config/server.conf | 46 +++++++++ .../hooks/down/10-network.sh | 22 +++++ .../hooks/finish/10-network.sh | 24 +++++ .../hooks/init/10-network.sh | 29 ++++++ .../basic_nat_wlp_ipv6/hooks/up/10-network.sh | 22 +++++ .../example/config/basic_nat_wlp_ipv6/wizard | 95 +++++++++++++++++++ .../config/basic_routed_ipv6/README.md | 48 ++++++++++ .../basic_routed_ipv6/client/client.conf | 34 +++++++ .../basic_routed_ipv6/config/server.conf | 46 +++++++++ .../hooks/down/10-network.sh | 18 ++++ .../hooks/finish/10-network.sh | 24 +++++ .../hooks/init/10-network.sh | 29 ++++++ .../basic_routed_ipv6/hooks/up/10-network.sh | 18 ++++ .../example/config/basic_routed_ipv6/wizard | 95 +++++++++++++++++++ 24 files changed, 908 insertions(+) create mode 100644 root/defaults/example/config/basic_nat_ipv6/README.md create mode 100644 root/defaults/example/config/basic_nat_ipv6/client/client.conf create mode 100644 root/defaults/example/config/basic_nat_ipv6/config/server.conf create mode 100755 root/defaults/example/config/basic_nat_ipv6/hooks/down/10-network.sh create mode 100755 root/defaults/example/config/basic_nat_ipv6/hooks/finish/10-network.sh create mode 100755 root/defaults/example/config/basic_nat_ipv6/hooks/init/10-network.sh create mode 100755 root/defaults/example/config/basic_nat_ipv6/hooks/up/10-network.sh create mode 100755 root/defaults/example/config/basic_nat_ipv6/wizard create mode 100644 root/defaults/example/config/basic_nat_wlp_ipv6/README.md create mode 100644 root/defaults/example/config/basic_nat_wlp_ipv6/client/client.conf create mode 100644 root/defaults/example/config/basic_nat_wlp_ipv6/config/server.conf create mode 100755 root/defaults/example/config/basic_nat_wlp_ipv6/hooks/down/10-network.sh create mode 100755 root/defaults/example/config/basic_nat_wlp_ipv6/hooks/finish/10-network.sh create mode 100755 root/defaults/example/config/basic_nat_wlp_ipv6/hooks/init/10-network.sh create mode 100755 root/defaults/example/config/basic_nat_wlp_ipv6/hooks/up/10-network.sh create mode 100755 root/defaults/example/config/basic_nat_wlp_ipv6/wizard create mode 100644 root/defaults/example/config/basic_routed_ipv6/README.md create mode 100644 root/defaults/example/config/basic_routed_ipv6/client/client.conf create mode 100644 root/defaults/example/config/basic_routed_ipv6/config/server.conf create mode 100755 root/defaults/example/config/basic_routed_ipv6/hooks/down/10-network.sh create mode 100755 root/defaults/example/config/basic_routed_ipv6/hooks/finish/10-network.sh create mode 100755 root/defaults/example/config/basic_routed_ipv6/hooks/init/10-network.sh create mode 100755 root/defaults/example/config/basic_routed_ipv6/hooks/up/10-network.sh create mode 100755 root/defaults/example/config/basic_routed_ipv6/wizard diff --git a/root/defaults/example/config/basic_nat_ipv6/README.md b/root/defaults/example/config/basic_nat_ipv6/README.md new file mode 100644 index 0000000..f269e58 --- /dev/null +++ b/root/defaults/example/config/basic_nat_ipv6/README.md @@ -0,0 +1,21 @@ +# basic_nat_ipv6 + +Features: + +- Works out of the box on bridge or host network +- NAT (Network translation protocol) +- Has configuration wizard +- LAN protection (does not allow traffic to LANs connected to server) + +## Configure + +``` bash +ovpn_enconf basic_nat +#Protocol udp, tcp, udp6, tcp6 [udp]: +#VPN network [10.0.0.0]: +#VPN IPv6 network with CIDR [2001:db8::/32]: +#Port [1194]: +#Public IP or domain of server: +#DNS1 [8.8.8.8]: +#DNS2 [8.8.4.4]: +``` diff --git a/root/defaults/example/config/basic_nat_ipv6/client/client.conf b/root/defaults/example/config/basic_nat_ipv6/client/client.conf new file mode 100644 index 0000000..5c956c7 --- /dev/null +++ b/root/defaults/example/config/basic_nat_ipv6/client/client.conf @@ -0,0 +1,34 @@ +# +# Basic OpenVPN server configuration +# @author Martin Dagarin +# @version 2 +# @since 12/03/2019 +# + +# Basic info +client +dev tun0 +proto $PROTO +nobind + +# Remote info +remote $SERVER_IP $PORT + +# Connection settings +resolv-retry infinite +persist-key +persist-tun + +# Encryption settings +cipher AES-256-GCM + +# Additional settings +compress lzo +verb 3 + +# Permissions +user nobody +group nogroup + +# CA +remote-cert-tls server diff --git a/root/defaults/example/config/basic_nat_ipv6/config/server.conf b/root/defaults/example/config/basic_nat_ipv6/config/server.conf new file mode 100644 index 0000000..4357abc --- /dev/null +++ b/root/defaults/example/config/basic_nat_ipv6/config/server.conf @@ -0,0 +1,46 @@ +# +# Basic OpenVPN server configuration +# @author Martin Dagarin +# @version 3 +# @since 12/03/2019 +# + +# Basic info +proto $PROTO +port $PORT + +# Network info (local VPN network) +topology subnet +server $NETWORK_ADDRESS 255.255.255.0 +server-ipv6 $NETWORK_ADDRESS_IPV6 + +push "redirect-gateway def1 bypass-dhcp" +push "route-ipv6 ::/0" +push "dhcp-option DNS $DNS1" +push "dhcp-option DNS $DNS2" + +ifconfig-pool-persist /config/tmp/ipp.txt + +# CA files +ca /config/pki/ca.crt +cert /config/pki/issued/server.crt +key /config/pki/private/server.key +dh /config/pki/dh.pem +tls-crypt /config/pki/ta.key +remote-cert-tls client + +# Connection settings +persist-key +persist-tun + +# Encryption settings +cipher AES-256-GCM + +# Verify client certificate +verify-client-cert require + +# Additional settings +client-to-client +keepalive 10 120 +compress lzo +explicit-exit-notify 1 diff --git a/root/defaults/example/config/basic_nat_ipv6/hooks/down/10-network.sh b/root/defaults/example/config/basic_nat_ipv6/hooks/down/10-network.sh new file mode 100755 index 0000000..760b4f8 --- /dev/null +++ b/root/defaults/example/config/basic_nat_ipv6/hooks/down/10-network.sh @@ -0,0 +1,27 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallDestroy.sh + +# +# Network clear +# +echo "Clearing OpenVPN releated firewall rules" + +# Close OpenVPN port to outside +ovpn-iptables -D INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" +ovpn-ip6tables -D INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" + +# Disable LAN protection of VPN +ovpn-iptables -D FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -d 10.0.0.0/8 -j REJECT -m comment --comment "Drop traffic VPN --> LANs" +ovpn-iptables -D FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -d 192.168.0.0/16 -j REJECT -m comment --comment "Drop traffic VPN --> LANs" +ovpn-iptables -D FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -d 172.16.0.0/12 -j REJECT -m comment --comment "Drop traffic VPN --> LANs" + +# Disable Routing Internet <--> VPN network +ovpn-iptables -D FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-iptables -D FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" +ovpn-ip6tables -D FORWARD -i tun0 -s $NETWORK_ADDRESS_IPV6 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-ip6tables -D FORWARD -i $OUT_INT -d $NETWORK_ADDRESS_IPV6 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" + +# Disable NAT for VPN traffic +ovpn-iptables -t nat -D POSTROUTING -s $NETWORK_ADDRESS/24 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" +ovpn-ip6tables -t nat -D POSTROUTING -s $NETWORK_ADDRESS_IPV6 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat_ipv6/hooks/finish/10-network.sh b/root/defaults/example/config/basic_nat_ipv6/hooks/finish/10-network.sh new file mode 100755 index 0000000..09d399e --- /dev/null +++ b/root/defaults/example/config/basic_nat_ipv6/hooks/finish/10-network.sh @@ -0,0 +1,24 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallDestroy.sh + +# +# Network clear +# +echo "Clearing up basic firewall rules" + +# Accept everything from input +ovpn-iptables -P INPUT ACCEPT +ovpn-ip6tables -P INPUT ACCEPT + +# Delete: Allow established connection +ovpn-iptables -D INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" +ovpn-ip6tables -D INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" + +# Delete: Allow ICMP ping request +ovpn-iptables -D INPUT -p icmp --icmp-type 8 -j ACCEPT +ovpn-ip6tables -D INPUT -p icmp --icmp-type 128 -j ACCEPT + +# Accept all forwarded traffic +ovpn-iptables -P FORWARD ACCEPT +ovpn-ip6tables -P FORWARD ACCEPT \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat_ipv6/hooks/init/10-network.sh b/root/defaults/example/config/basic_nat_ipv6/hooks/init/10-network.sh new file mode 100755 index 0000000..3ab599e --- /dev/null +++ b/root/defaults/example/config/basic_nat_ipv6/hooks/init/10-network.sh @@ -0,0 +1,29 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallSetup.sh + +# +# Network initialization +# +echo "Setting up basic firewall rules" + +# +# Because default iptables rules are set to ACCEPT all connection, we need to put some +# security settings in place +# + +# Drop everything from input +ovpn-iptables -P INPUT DROP +ovpn-ip6tables -P INPUT DROP + +# Allow established connection +ovpn-iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" +ovpn-ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" + +# Allow ICMP ping request +ovpn-iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT +ovpn-ip6tables -A INPUT -p icmp --icmp-type 128 -j ACCEPT + +# Drop all forwarded traffic +ovpn-iptables -P FORWARD DROP +ovpn-ip6tables -P FORWARD DROP \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat_ipv6/hooks/up/10-network.sh b/root/defaults/example/config/basic_nat_ipv6/hooks/up/10-network.sh new file mode 100755 index 0000000..4c9373b --- /dev/null +++ b/root/defaults/example/config/basic_nat_ipv6/hooks/up/10-network.sh @@ -0,0 +1,27 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallSetup.sh + +# +# Network initialization +# +echo "Setting up OpenVPN related firewall rules" + +# Open OpenVPN port to outside +ovpn-iptables -A INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" +ovpn-ip6tables -A INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" + +# Protect LANs after VPN +ovpn-iptables -A FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -d 10.0.0.0/8 -j REJECT -m comment --comment "Drop traffic VPN --> LANs" +ovpn-iptables -A FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -d 192.168.0.0/16 -j REJECT -m comment --comment "Drop traffic VPN --> LANs" +ovpn-iptables -A FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -d 172.16.0.0/12 -j REJECT -m comment --comment "Drop traffic VPN --> LANs" + +# Allow Routing Internet <--> VPN network +ovpn-iptables -A FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-iptables -A FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" +ovpn-ip6tables -A FORWARD -i tun0 -s $NETWORK_ADDRESS_IPV6 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-ip6tables -A FORWARD -i $OUT_INT -d $NETWORK_ADDRESS_IPV6 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" + +# Preform NAT for VPN traffic +ovpn-iptables -t nat -A POSTROUTING -s $NETWORK_ADDRESS/24 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" +ovpn-ip6tables -t nat -A POSTROUTING -s $NETWORK_ADDRESS_IPV6 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat_ipv6/wizard b/root/defaults/example/config/basic_nat_ipv6/wizard new file mode 100755 index 0000000..a76cf2b --- /dev/null +++ b/root/defaults/example/config/basic_nat_ipv6/wizard @@ -0,0 +1,95 @@ +#!/usr/bin/python + +# +# Config wizard for basic_nat example +# @author Martin Dagarin +# @version 1 +# @since 19/03/2019 +# + +# Defaults: +# Protocol: udp +# Network: 10.0.0.0 +# Port: 1194 +# DNS: 8.8.8.8, 2001:4860:4860::8888 +# + +import sys, os + +# Import libraries included in this docker +sys.path.insert(0, '/app') +import libovpn + +# Check if temporary path was passed to this script +if len(sys.argv) < 2: + print("Temporary path was not passed to wizard") + sys.exit(1) +TEMP_PATH = sys.argv[1] +if not os.path.isdir(TEMP_PATH): + print("Specified directory does not exist") + sys.exit(2) + +# Select output interface +out_int = input("Out interface [eth0]:") +if len(out_int) == 0: + out_int = "eth0" + +# Select protocol +protocol = input("Protocol udp, tcp, udp6, tcp6 [udp]:") +AVAILABLE_PROTOCOLS = ["udp", "tcp", "udp6", "tcp6"] +if len(protocol) != 0 and protocol not in AVAILABLE_PROTOCOLS: + print("Invalid protocol") + sys.exit(3) +if len(protocol) == 0: + protocol = "udp" + +# Select network +network = input("VPN network [10.0.0.0]:") +if len(network) == 0: + network = "10.0.0.0" +networkv6 = input("VPN IPv6 network with CIDR [2001:db8::/32]:") +if len(network) == 0: + print("Invalid network") + sys.exit(4) + +# Select port +port = input("Port [1194]:") +if len(port) == 0: + port="1194" + +# Select Public IP or domain +public = input("Public IP or domain of server:") +if len(public) == 0: + print("Invalid Public IP") + sys.exit(5) + +# DNS servers +dns1 = input("DNS1 [8.8.8.8]:") +if len(dns1) == 0: + dns1 = "8.8.8.8" +dns2 = input("DNS2 [2001:4860:4860::8888]:") +if len(dns2) == 0: + dns2 = "2001:4860:4860::8888" + + +# Write to server config +vars = [ + ("$OUT_INT", out_int), + ("$PROTO", protocol), + ("$PORT", port), + ("$NETWORK_ADDRESS", network), + ("$NETWORK_ADDRESS_IPV6", networkv6), + ("$SERVER_IP", public), + ("$DNS1", dns1), + ("$DNS2", dns2) +] + +# Process config files +confs = [ + "/config/server.conf", + "/client/client.conf", + "/hooks/down/10-network.sh", + "/hooks/up/10-network.sh" +] +for config_file in confs: + libovpn.conf_envsubst(TEMP_PATH + config_file, vars) \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat_wlp_ipv6/README.md b/root/defaults/example/config/basic_nat_wlp_ipv6/README.md new file mode 100644 index 0000000..f402e3f --- /dev/null +++ b/root/defaults/example/config/basic_nat_wlp_ipv6/README.md @@ -0,0 +1,21 @@ +# basic_nat_wlp_ipv6 + +Features: + +- Works out of the box on bridge or host network +- NAT (Network translation protocol) +- Has configuration wizard +- **WITHOUT** LAN protection (does not allow traffic to LANs connected to server), so you can still access devices in LAN (but **routed** example is recommended, because here traffic is still NAT-ed) + +## Configure + +``` bash +ovpn_enconf basic_nat +#Protocol udp, tcp, udp6, tcp6 [udp]: +#VPN network [10.0.0.0]: +#VPN IPv6 network with CIDR [2001:db8::/32]: +#Port [1194]: +#Public IP or domain of server: +#DNS1 [8.8.8.8]: +#DNS2 [8.8.4.4]: +``` diff --git a/root/defaults/example/config/basic_nat_wlp_ipv6/client/client.conf b/root/defaults/example/config/basic_nat_wlp_ipv6/client/client.conf new file mode 100644 index 0000000..5c956c7 --- /dev/null +++ b/root/defaults/example/config/basic_nat_wlp_ipv6/client/client.conf @@ -0,0 +1,34 @@ +# +# Basic OpenVPN server configuration +# @author Martin Dagarin +# @version 2 +# @since 12/03/2019 +# + +# Basic info +client +dev tun0 +proto $PROTO +nobind + +# Remote info +remote $SERVER_IP $PORT + +# Connection settings +resolv-retry infinite +persist-key +persist-tun + +# Encryption settings +cipher AES-256-GCM + +# Additional settings +compress lzo +verb 3 + +# Permissions +user nobody +group nogroup + +# CA +remote-cert-tls server diff --git a/root/defaults/example/config/basic_nat_wlp_ipv6/config/server.conf b/root/defaults/example/config/basic_nat_wlp_ipv6/config/server.conf new file mode 100644 index 0000000..4357abc --- /dev/null +++ b/root/defaults/example/config/basic_nat_wlp_ipv6/config/server.conf @@ -0,0 +1,46 @@ +# +# Basic OpenVPN server configuration +# @author Martin Dagarin +# @version 3 +# @since 12/03/2019 +# + +# Basic info +proto $PROTO +port $PORT + +# Network info (local VPN network) +topology subnet +server $NETWORK_ADDRESS 255.255.255.0 +server-ipv6 $NETWORK_ADDRESS_IPV6 + +push "redirect-gateway def1 bypass-dhcp" +push "route-ipv6 ::/0" +push "dhcp-option DNS $DNS1" +push "dhcp-option DNS $DNS2" + +ifconfig-pool-persist /config/tmp/ipp.txt + +# CA files +ca /config/pki/ca.crt +cert /config/pki/issued/server.crt +key /config/pki/private/server.key +dh /config/pki/dh.pem +tls-crypt /config/pki/ta.key +remote-cert-tls client + +# Connection settings +persist-key +persist-tun + +# Encryption settings +cipher AES-256-GCM + +# Verify client certificate +verify-client-cert require + +# Additional settings +client-to-client +keepalive 10 120 +compress lzo +explicit-exit-notify 1 diff --git a/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/down/10-network.sh b/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/down/10-network.sh new file mode 100755 index 0000000..0ad1e45 --- /dev/null +++ b/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/down/10-network.sh @@ -0,0 +1,22 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallDestroy.sh + +# +# Network clear +# +echo "Clearing OpenVPN releated firewall rules" + +# Close OpenVPN port to outside +ovpn-iptables -D INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" +ovpn-ip6tables -D INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" + +# Disable Routing Internet <--> VPN network +ovpn-iptables -D FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-iptables -D FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" +ovpn-ip6tables -D FORWARD -i tun0 -s $NETWORK_ADDRESS_IPV6 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-ip6tables -D FORWARD -i $OUT_INT -d $NETWORK_ADDRESS_IPV6 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" + +# Disable NAT for VPN traffic +ovpn-iptables -t nat -D POSTROUTING -s $NETWORK_ADDRESS/24 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" +ovpn-ip6tables -t nat -D POSTROUTING -s $NETWORK_ADDRESS_IPV6 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/finish/10-network.sh b/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/finish/10-network.sh new file mode 100755 index 0000000..09d399e --- /dev/null +++ b/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/finish/10-network.sh @@ -0,0 +1,24 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallDestroy.sh + +# +# Network clear +# +echo "Clearing up basic firewall rules" + +# Accept everything from input +ovpn-iptables -P INPUT ACCEPT +ovpn-ip6tables -P INPUT ACCEPT + +# Delete: Allow established connection +ovpn-iptables -D INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" +ovpn-ip6tables -D INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" + +# Delete: Allow ICMP ping request +ovpn-iptables -D INPUT -p icmp --icmp-type 8 -j ACCEPT +ovpn-ip6tables -D INPUT -p icmp --icmp-type 128 -j ACCEPT + +# Accept all forwarded traffic +ovpn-iptables -P FORWARD ACCEPT +ovpn-ip6tables -P FORWARD ACCEPT \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/init/10-network.sh b/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/init/10-network.sh new file mode 100755 index 0000000..3ab599e --- /dev/null +++ b/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/init/10-network.sh @@ -0,0 +1,29 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallSetup.sh + +# +# Network initialization +# +echo "Setting up basic firewall rules" + +# +# Because default iptables rules are set to ACCEPT all connection, we need to put some +# security settings in place +# + +# Drop everything from input +ovpn-iptables -P INPUT DROP +ovpn-ip6tables -P INPUT DROP + +# Allow established connection +ovpn-iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" +ovpn-ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" + +# Allow ICMP ping request +ovpn-iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT +ovpn-ip6tables -A INPUT -p icmp --icmp-type 128 -j ACCEPT + +# Drop all forwarded traffic +ovpn-iptables -P FORWARD DROP +ovpn-ip6tables -P FORWARD DROP \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/up/10-network.sh b/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/up/10-network.sh new file mode 100755 index 0000000..2fec22a --- /dev/null +++ b/root/defaults/example/config/basic_nat_wlp_ipv6/hooks/up/10-network.sh @@ -0,0 +1,22 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallSetup.sh + +# +# Network initialization +# +echo "Setting up OpenVPN related firewall rules" + +# Open OpenVPN port to outside +ovpn-iptables -A INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" +ovpn-ip6tables -A INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" + +# Allow Routing Internet <--> VPN network +ovpn-iptables -A FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-iptables -A FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" +ovpn-ip6tables -A FORWARD -i tun0 -s $NETWORK_ADDRESS_IPV6 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-ip6tables -A FORWARD -i $OUT_INT -d $NETWORK_ADDRESS_IPV6 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" + +# Preform NAT for VPN traffic +ovpn-iptables -t nat -A POSTROUTING -s $NETWORK_ADDRESS/24 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" +ovpn-ip6tables -t nat -A POSTROUTING -s $NETWORK_ADDRESS_IPV6 -o $OUT_INT -j MASQUERADE -m comment --comment "NAT traffic VPN --> Internet" \ No newline at end of file diff --git a/root/defaults/example/config/basic_nat_wlp_ipv6/wizard b/root/defaults/example/config/basic_nat_wlp_ipv6/wizard new file mode 100755 index 0000000..a76cf2b --- /dev/null +++ b/root/defaults/example/config/basic_nat_wlp_ipv6/wizard @@ -0,0 +1,95 @@ +#!/usr/bin/python + +# +# Config wizard for basic_nat example +# @author Martin Dagarin +# @version 1 +# @since 19/03/2019 +# + +# Defaults: +# Protocol: udp +# Network: 10.0.0.0 +# Port: 1194 +# DNS: 8.8.8.8, 2001:4860:4860::8888 +# + +import sys, os + +# Import libraries included in this docker +sys.path.insert(0, '/app') +import libovpn + +# Check if temporary path was passed to this script +if len(sys.argv) < 2: + print("Temporary path was not passed to wizard") + sys.exit(1) +TEMP_PATH = sys.argv[1] +if not os.path.isdir(TEMP_PATH): + print("Specified directory does not exist") + sys.exit(2) + +# Select output interface +out_int = input("Out interface [eth0]:") +if len(out_int) == 0: + out_int = "eth0" + +# Select protocol +protocol = input("Protocol udp, tcp, udp6, tcp6 [udp]:") +AVAILABLE_PROTOCOLS = ["udp", "tcp", "udp6", "tcp6"] +if len(protocol) != 0 and protocol not in AVAILABLE_PROTOCOLS: + print("Invalid protocol") + sys.exit(3) +if len(protocol) == 0: + protocol = "udp" + +# Select network +network = input("VPN network [10.0.0.0]:") +if len(network) == 0: + network = "10.0.0.0" +networkv6 = input("VPN IPv6 network with CIDR [2001:db8::/32]:") +if len(network) == 0: + print("Invalid network") + sys.exit(4) + +# Select port +port = input("Port [1194]:") +if len(port) == 0: + port="1194" + +# Select Public IP or domain +public = input("Public IP or domain of server:") +if len(public) == 0: + print("Invalid Public IP") + sys.exit(5) + +# DNS servers +dns1 = input("DNS1 [8.8.8.8]:") +if len(dns1) == 0: + dns1 = "8.8.8.8" +dns2 = input("DNS2 [2001:4860:4860::8888]:") +if len(dns2) == 0: + dns2 = "2001:4860:4860::8888" + + +# Write to server config +vars = [ + ("$OUT_INT", out_int), + ("$PROTO", protocol), + ("$PORT", port), + ("$NETWORK_ADDRESS", network), + ("$NETWORK_ADDRESS_IPV6", networkv6), + ("$SERVER_IP", public), + ("$DNS1", dns1), + ("$DNS2", dns2) +] + +# Process config files +confs = [ + "/config/server.conf", + "/client/client.conf", + "/hooks/down/10-network.sh", + "/hooks/up/10-network.sh" +] +for config_file in confs: + libovpn.conf_envsubst(TEMP_PATH + config_file, vars) \ No newline at end of file diff --git a/root/defaults/example/config/basic_routed_ipv6/README.md b/root/defaults/example/config/basic_routed_ipv6/README.md new file mode 100644 index 0000000..9a67b2e --- /dev/null +++ b/root/defaults/example/config/basic_routed_ipv6/README.md @@ -0,0 +1,48 @@ +# basic_routed_ipv6 + +Features: + +- Has configuration wizard +- Prepared for using routing (so you will have access to LANs directly without using NAT) + +## Configure + +``` bash +ovpn_enconf basic_routed +#Protocol udp, tcp, udp6, tcp6 [udp]: +#VPN network [10.0.0.0]: +#VPN IPv6 network with CIDR [2001:db8::/32]: +#Port [1194]: +#Public IP or domain of server: +#DNS1 [8.8.8.8]: +#DNS2 [8.8.4.4]: +``` + +### Network configuration + +1. If you are using **bridge** networking mode else skip this step: + + - Assign static IP to this container + - see [docker compose networks](https://docs.docker.com/compose/compose-file/compose-file-v2/#networks), you can also check current IP of container + with `docker exec -it CONTAINERNAME ifconfig` + - Add static route on host to the container with network + + ``` bash + route add -net NETWORK netmask MASK gw CONTAINER_IP + ``` + +2. Add route to the network on your router + + - Destination IP Address: NETWORK + - Subnet mask: MASK + - Gateway: SERVERIP_OR_CONTAINERIP (IP where your OpenVPN server is running: server ip when bridge mode, container ip on host mode) + + ![Sample interface](img/img1.png) + +3. If you have Mikrotik or Cisco router make sure you have NAT correctly configured +4. Make sure you have firewall rules correctly configured on your router +5. Add additional routes in *server config* if nessesary (see [--route option](https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage)), default route is set as default gateway + + ``` OpenVPN + route network/IP [netmask] [gateway] [metric] + ``` diff --git a/root/defaults/example/config/basic_routed_ipv6/client/client.conf b/root/defaults/example/config/basic_routed_ipv6/client/client.conf new file mode 100644 index 0000000..5c956c7 --- /dev/null +++ b/root/defaults/example/config/basic_routed_ipv6/client/client.conf @@ -0,0 +1,34 @@ +# +# Basic OpenVPN server configuration +# @author Martin Dagarin +# @version 2 +# @since 12/03/2019 +# + +# Basic info +client +dev tun0 +proto $PROTO +nobind + +# Remote info +remote $SERVER_IP $PORT + +# Connection settings +resolv-retry infinite +persist-key +persist-tun + +# Encryption settings +cipher AES-256-GCM + +# Additional settings +compress lzo +verb 3 + +# Permissions +user nobody +group nogroup + +# CA +remote-cert-tls server diff --git a/root/defaults/example/config/basic_routed_ipv6/config/server.conf b/root/defaults/example/config/basic_routed_ipv6/config/server.conf new file mode 100644 index 0000000..4357abc --- /dev/null +++ b/root/defaults/example/config/basic_routed_ipv6/config/server.conf @@ -0,0 +1,46 @@ +# +# Basic OpenVPN server configuration +# @author Martin Dagarin +# @version 3 +# @since 12/03/2019 +# + +# Basic info +proto $PROTO +port $PORT + +# Network info (local VPN network) +topology subnet +server $NETWORK_ADDRESS 255.255.255.0 +server-ipv6 $NETWORK_ADDRESS_IPV6 + +push "redirect-gateway def1 bypass-dhcp" +push "route-ipv6 ::/0" +push "dhcp-option DNS $DNS1" +push "dhcp-option DNS $DNS2" + +ifconfig-pool-persist /config/tmp/ipp.txt + +# CA files +ca /config/pki/ca.crt +cert /config/pki/issued/server.crt +key /config/pki/private/server.key +dh /config/pki/dh.pem +tls-crypt /config/pki/ta.key +remote-cert-tls client + +# Connection settings +persist-key +persist-tun + +# Encryption settings +cipher AES-256-GCM + +# Verify client certificate +verify-client-cert require + +# Additional settings +client-to-client +keepalive 10 120 +compress lzo +explicit-exit-notify 1 diff --git a/root/defaults/example/config/basic_routed_ipv6/hooks/down/10-network.sh b/root/defaults/example/config/basic_routed_ipv6/hooks/down/10-network.sh new file mode 100755 index 0000000..30c83dd --- /dev/null +++ b/root/defaults/example/config/basic_routed_ipv6/hooks/down/10-network.sh @@ -0,0 +1,18 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallDestroy.sh + +# +# Network clear +# +echo "Clearing OpenVPN releated firewall rules" + +# Close OpenVPN port to outside +ovpn-iptables -D INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" +ovpn-ip6tables -D INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" + +# Disable Routing Internet <--> VPN network +ovpn-iptables -D FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-iptables -D FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" +ovpn-ip6tables -D FORWARD -i tun0 -s $NETWORK_ADDRESS_IPV6 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-ip6tables -D FORWARD -i $OUT_INT -d $NETWORK_ADDRESS_IPV6 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" diff --git a/root/defaults/example/config/basic_routed_ipv6/hooks/finish/10-network.sh b/root/defaults/example/config/basic_routed_ipv6/hooks/finish/10-network.sh new file mode 100755 index 0000000..09d399e --- /dev/null +++ b/root/defaults/example/config/basic_routed_ipv6/hooks/finish/10-network.sh @@ -0,0 +1,24 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallDestroy.sh + +# +# Network clear +# +echo "Clearing up basic firewall rules" + +# Accept everything from input +ovpn-iptables -P INPUT ACCEPT +ovpn-ip6tables -P INPUT ACCEPT + +# Delete: Allow established connection +ovpn-iptables -D INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" +ovpn-ip6tables -D INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" + +# Delete: Allow ICMP ping request +ovpn-iptables -D INPUT -p icmp --icmp-type 8 -j ACCEPT +ovpn-ip6tables -D INPUT -p icmp --icmp-type 128 -j ACCEPT + +# Accept all forwarded traffic +ovpn-iptables -P FORWARD ACCEPT +ovpn-ip6tables -P FORWARD ACCEPT \ No newline at end of file diff --git a/root/defaults/example/config/basic_routed_ipv6/hooks/init/10-network.sh b/root/defaults/example/config/basic_routed_ipv6/hooks/init/10-network.sh new file mode 100755 index 0000000..3ab599e --- /dev/null +++ b/root/defaults/example/config/basic_routed_ipv6/hooks/init/10-network.sh @@ -0,0 +1,29 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallSetup.sh + +# +# Network initialization +# +echo "Setting up basic firewall rules" + +# +# Because default iptables rules are set to ACCEPT all connection, we need to put some +# security settings in place +# + +# Drop everything from input +ovpn-iptables -P INPUT DROP +ovpn-ip6tables -P INPUT DROP + +# Allow established connection +ovpn-iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" +ovpn-ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "Accept traffic from established connections" + +# Allow ICMP ping request +ovpn-iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT +ovpn-ip6tables -A INPUT -p icmp --icmp-type 128 -j ACCEPT + +# Drop all forwarded traffic +ovpn-iptables -P FORWARD DROP +ovpn-ip6tables -P FORWARD DROP \ No newline at end of file diff --git a/root/defaults/example/config/basic_routed_ipv6/hooks/up/10-network.sh b/root/defaults/example/config/basic_routed_ipv6/hooks/up/10-network.sh new file mode 100755 index 0000000..664795d --- /dev/null +++ b/root/defaults/example/config/basic_routed_ipv6/hooks/up/10-network.sh @@ -0,0 +1,18 @@ +#!/usr/bin/with-contenv bash + +source /app/hookBaseFirewallSetup.sh + +# +# Network initialization +# +echo "Setting up OpenVPN related firewall rules" + +# Open OpenVPN port to outside +ovpn-iptables -A INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" +ovpn-ip6tables -A INPUT -p udp -m udp --dport $PORT -j ACCEPT -m comment --comment "Open OpenVPN port" + +# Allow Routing Internet <--> VPN network +ovpn-iptables -A FORWARD -i tun0 -s $NETWORK_ADDRESS/24 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-iptables -A FORWARD -i $OUT_INT -d $NETWORK_ADDRESS/24 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" +ovpn-ip6tables -A FORWARD -i tun0 -s $NETWORK_ADDRESS_IPV6 -o $OUT_INT -j ACCEPT -m comment --comment "Allow traffic VPN --> Internet" +ovpn-ip6tables -A FORWARD -i $OUT_INT -d $NETWORK_ADDRESS_IPV6 -o tun0 -j ACCEPT -m comment --comment "Allow traffic Internet --> VPN" diff --git a/root/defaults/example/config/basic_routed_ipv6/wizard b/root/defaults/example/config/basic_routed_ipv6/wizard new file mode 100755 index 0000000..a76cf2b --- /dev/null +++ b/root/defaults/example/config/basic_routed_ipv6/wizard @@ -0,0 +1,95 @@ +#!/usr/bin/python + +# +# Config wizard for basic_nat example +# @author Martin Dagarin +# @version 1 +# @since 19/03/2019 +# + +# Defaults: +# Protocol: udp +# Network: 10.0.0.0 +# Port: 1194 +# DNS: 8.8.8.8, 2001:4860:4860::8888 +# + +import sys, os + +# Import libraries included in this docker +sys.path.insert(0, '/app') +import libovpn + +# Check if temporary path was passed to this script +if len(sys.argv) < 2: + print("Temporary path was not passed to wizard") + sys.exit(1) +TEMP_PATH = sys.argv[1] +if not os.path.isdir(TEMP_PATH): + print("Specified directory does not exist") + sys.exit(2) + +# Select output interface +out_int = input("Out interface [eth0]:") +if len(out_int) == 0: + out_int = "eth0" + +# Select protocol +protocol = input("Protocol udp, tcp, udp6, tcp6 [udp]:") +AVAILABLE_PROTOCOLS = ["udp", "tcp", "udp6", "tcp6"] +if len(protocol) != 0 and protocol not in AVAILABLE_PROTOCOLS: + print("Invalid protocol") + sys.exit(3) +if len(protocol) == 0: + protocol = "udp" + +# Select network +network = input("VPN network [10.0.0.0]:") +if len(network) == 0: + network = "10.0.0.0" +networkv6 = input("VPN IPv6 network with CIDR [2001:db8::/32]:") +if len(network) == 0: + print("Invalid network") + sys.exit(4) + +# Select port +port = input("Port [1194]:") +if len(port) == 0: + port="1194" + +# Select Public IP or domain +public = input("Public IP or domain of server:") +if len(public) == 0: + print("Invalid Public IP") + sys.exit(5) + +# DNS servers +dns1 = input("DNS1 [8.8.8.8]:") +if len(dns1) == 0: + dns1 = "8.8.8.8" +dns2 = input("DNS2 [2001:4860:4860::8888]:") +if len(dns2) == 0: + dns2 = "2001:4860:4860::8888" + + +# Write to server config +vars = [ + ("$OUT_INT", out_int), + ("$PROTO", protocol), + ("$PORT", port), + ("$NETWORK_ADDRESS", network), + ("$NETWORK_ADDRESS_IPV6", networkv6), + ("$SERVER_IP", public), + ("$DNS1", dns1), + ("$DNS2", dns2) +] + +# Process config files +confs = [ + "/config/server.conf", + "/client/client.conf", + "/hooks/down/10-network.sh", + "/hooks/up/10-network.sh" +] +for config_file in confs: + libovpn.conf_envsubst(TEMP_PATH + config_file, vars) \ No newline at end of file From ac14c502785ccce02bd8560e472702de8e0f6ed1 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 30 Jul 2019 01:09:17 +0200 Subject: [PATCH 13/14] Changed base image https://github.com/SloCompTech/docker-baseimage --- CHANGELOG.md | 2 ++ Dockerfile | 9 +++-- Dockerfile.armhf | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 Dockerfile.armhf diff --git a/CHANGELOG.md b/CHANGELOG.md index 999f04d..00ec534 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - Hiearhicaly moved all commands under the hood of `ovpn` command - Improved backup command - Added restore command +- Changed base image +- Added **armhf** build ### 1.0.6 - Bugfix diff --git a/Dockerfile b/Dockerfile index fde4921..f81ef80 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,8 @@ # # Base image -# @see https://github.com/linuxserver/docker-baseimage-alpine -# @see https://github.com/linuxserver/docker-baseimage-alpine-python3 +# @see https://github.com/SloCompTech/docker-baseimage # -FROM slocomptech/baseimage-alpine +FROM slocomptech/baseimage:alpine # Build arguments ARG BUILD_DATE @@ -64,7 +63,7 @@ RUN apk add --no-cache \ # Remove any temporary files created by apk rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/* && \ # Add permission for network management to user abc - echo "abc ALL=(ALL) NOPASSWD: \ + echo "${CONTAINER_USER} ALL=(ALL) NOPASSWD: \ /sbin/ip, \ /sbin/ip6tables, \ /sbin/ip6tables-compat, \ @@ -83,7 +82,7 @@ RUN apk add --no-cache \ /sbin/iptables-save, \ /sbin/iptables-translate, \ /sbin/route" \ - >> /etc/sudoers.d/abc + >> /etc/sudoers.d/${CONTAINER_USER} # Add repo files to image COPY root/ / diff --git a/Dockerfile.armhf b/Dockerfile.armhf new file mode 100644 index 0000000..aeaaaf5 --- /dev/null +++ b/Dockerfile.armhf @@ -0,0 +1,88 @@ +# +# Base image +# @see https://github.com/SloCompTech/docker-baseimage +# +FROM slocomptech/baseimage:alpine-armhf + +# Build arguments +ARG BUILD_DATE +ARG VCS_REF +ARG VCS_SRC +ARG VERSION + +# +# Image labels +# @see https://github.com/opencontainers/image-spec/blob/master/annotations.md +# @see http://label-schema.org/rc1/ +# @see https://semver.org/ +# +LABEL org.opencontainers.image.title="OpenVPN Server" \ + org.label-schema.name="OpenVPN Server" \ + org.opencontainers.image.description="Docker image with OpenVPN server" \ + org.label-schema.description="Docker image with OpenVPN server" \ + org.opencontainers.image.url="https://github.com/SloCompTech/docker-openvpn" \ + org.label-schema.url="https://github.com/SloCompTech/docker-openvpn" \ + org.opencontainers.image.authors="Martin Dagarin " \ + org.opencontainers.image.version=$VERSION \ + org.label-schema.version=$VERSION \ + org.opencontainers.image.revision=$VCS_REF \ + org.label-schema.vcs-ref=$VCS_REF \ + org.opencontainers.image.source=$VCS_SRC \ + org.label-schema.vcs-url=$VCS_SRC \ + org.opencontainers.image.created=$BUILD_DATE \ + org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.schema-version="1.0" + + +# +# Environment variables +# @see https://github.com/OpenVPN/easy-rsa/blob/master/doc/EasyRSA-Advanced.md +# +ENV EASYRSA=/usr/share/easy-rsa \ + EASYRSA_PKI=/config/pki \ + EASYRSA_VARS_FILE=/config/ssl/vars \ + #EASYRSA_SSL_CONF=/config/ssl/openssl-easyrsa.cnf \ + EASYRSA_SAFE_CONF=/config/ssl/safessl-easyrsa.cnf \ + EASYRSA_TEMP_FILE=/config/tmp/temp + +# Install packages +RUN apk add --no-cache \ + # Core packages + bash \ + easy-rsa \ + iptables \ + ip6tables \ + openvpn \ + python3 \ + sudo && \ + # Link easy-rsa in bin directory + ln -s ${EASYRSA}/easyrsa /usr/local/bin && \ + # Link python3 also as python + ln -s /usr/bin/pip3 /usr/bin/pip && \ + ln -s /usr/bin/python3 /usr/bin/python && \ + # Remove any temporary files created by apk + rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/* && \ + # Add permission for network management to user abc + echo "${CONTAINER_USER} ALL=(ALL) NOPASSWD: \ + /sbin/ip, \ + /sbin/ip6tables, \ + /sbin/ip6tables-compat, \ + /sbin/ip6tables-compat-restore, \ + /sbin/ip6tables-compat-save, \ + /sbin/ip6tables-restore, \ + /sbin/ip6tables-restore-translate, \ + /sbin/ip6tables-save, \ + /sbin/ip6tables-translate, \ + /sbin/iptables, \ + /sbin/iptables-compat, \ + /sbin/iptables-compat-restore, \ + /sbin/iptables-compat-save, \ + /sbin/iptables-restore, \ + /sbin/iptables-restore-translate, \ + /sbin/iptables-save, \ + /sbin/iptables-translate, \ + /sbin/route" \ + >> /etc/sudoers.d/${CONTAINER_USER} + +# Add repo files to image +COPY root/ / From 3aca21b53ecc7e786765ade71895be73dc34d2d2 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 30 Jul 2019 01:09:39 +0200 Subject: [PATCH 14/14] Improved docs --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index d94c928..316b4e9 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,10 @@ For more infromation see: - **configuration example directory** (for more info about example) - [Contributing](CONTRIBUTING.md) (for explanation how container works, how to write an example config ...) +### Client mode + +Just put *.ovpn* file in `/config/openvpn/config` and restart container. + ## Troubleshooting - [OpenVPN troubleshoot guide](https://community.openvpn.net/openvpn/wiki/HOWTO#Troubleshooting)