Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Templating of Server Config & Monitoring #168

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ done.txt
/client/
.git
.gitignore
/docs/
/docs/
vpndata
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ tests-report/
test-reports/
target
.vscode/
ipv6-leack-test.sh
ipv6-leack-test.sh
vpndata
13 changes: 8 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,28 @@ LABEL maintainer="Alexander Litvinenko <array.shift@yahoo.com>"
ENV APP_NAME Dockovpn
ENV APP_INSTALL_PATH /opt/${APP_NAME}
ENV APP_PERSIST_DIR /opt/${APP_NAME}_data
ENV NET_ADAPTER eth0

WORKDIR ${APP_INSTALL_PATH}

COPY scripts .
COPY config ./config
COPY VERSION ./config

RUN apk add --no-cache openvpn easy-rsa bash netcat-openbsd zip dumb-init && \
RUN apk add --no-cache python3 py-pip openvpn easy-rsa bash netcat-openbsd zip dumb-init && \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thoroughly reviewed the templating part and it's truly amazing! However it brings in another execution environment i.e python and package dependencies which leads to much greater image size. At the moment I'd like to keep resulting image as small as possible for the benefit of embedded and RISK architectures.
Screenshot 2022-09-05 at 23 22 45

ln -s /usr/share/easy-rsa/easyrsa /usr/bin/easyrsa && \
mkdir -p ${APP_PERSIST_DIR} && \
cd ${APP_PERSIST_DIR} && \
mkdir -p /build && \
cd /build && \
easyrsa init-pki && \
easyrsa gen-dh && \
# DH parameters of size 2048 created at /usr/share/easy-rsa/pki/dh.pem
# Copy DH file
cp pki/dh.pem /etc/openvpn && \
# Copy FROM ./scripts/server/conf TO /etc/openvpn/server.conf in DockerFile
cd ${APP_INSTALL_PATH} && \
cp config/server.conf /etc/openvpn/server.conf
cd ${APP_INSTALL_PATH} && \
pip install cookiecutter && \
mkdir -p /etc/openvpn


EXPOSE 1194/udp
Expand All @@ -32,4 +35,4 @@ EXPOSE 8080/tcp
VOLUME [ "/opt/Dockovpn_data" ]

ENTRYPOINT [ "dumb-init", "./start.sh" ]
CMD [ "" ]
CMD [ "" ]
10 changes: 10 additions & 0 deletions config/cookiecutter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "server",
"port": "1194",
"protocol": "udp",
"ip_base": "10.8.0.0",
"ip_base_mask": "255.255.255.0",
"dns1": "208.67.222.222",
"dns2": "208.67.222.220",
"client2client": "true"
}
25 changes: 0 additions & 25 deletions config/server.conf

This file was deleted.

32 changes: 32 additions & 0 deletions config/{{cookiecutter.name}}/server.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
port {{cookiecutter.port}}
proto {{cookiecutter.protocol}}
dev tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/MyReq.crt
key /etc/openvpn/MyReq.key
dh /etc/openvpn/dh.pem
client-config-dir /etc/openvpn/ccd
{% if cookiecutter.client2client == true %}
client-to-client
{% endif %}
ifconfig-pool-persist ipp.txt
duplicate-cn
keepalive 10 120
cipher AES-256-GCM
ncp-ciphers AES-256-GCM:AES-256-CBC
auth SHA512
persist-key
persist-tun
status openvpn-status.log
verb 1
management 0.0.0.0 5555
tls-server
tls-version-min 1.2
tls-auth /etc/openvpn/ta.key 0
crl-verify /etc/openvpn/crl.pem
management 0.0.0.0 5555
server {{cookiecutter.ip_base}} {{cookiecutter.ip_base_mask}}
push "redirect-gateway def1 bypass-dhcp"
push "route {{cookiecutter.ip_base}} {{cookiecutter.ip_base_mask}}"
push "dhcp-option DNS {{cookiecutter.dns1}}"
push "dhcp-option DNS {{cookiecutter.dns2}}"
29 changes: 27 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,38 @@
version: '3'
services:
dockovpn:
image: alekslitvinenk/openvpn
# image: alekslitvinenk/openvpn
build:
context: .
dockerfile: Dockerfile
cap_add:
- NET_ADMIN
ports:
- 1194:1194/udp
environment:
HOST_ADDR: ${HOST_ADDR}
HOST_ADDR: ${HOST_ADDR}
PORT: 1194
PROTOCOL: udp
IP_BASE: "10.8.0.0"
IP_BASE_MASK: "255.255.255.0"
IP_NET: "10.8.0.0/24"
volumes:
- ./openvpn_conf:/doc/Dockovpn
restart: always
monitor:
image: ruimarinho/openvpn-monitor:latest
ports:
- 8081:80
environment:
OPENVPNMONITOR_DEFAULT_DATETIMEFORMAT: "%%d/%%m/%%Y"
OPENVPNMONITOR_DEFAULT_LATITUDE: -37
OPENVPNMONITOR_DEFAULT_LOGO: logo.jpg
OPENVPNMONITOR_DEFAULT_LONGITUDE: 144
OPENVPNMONITOR_DEFAULT_MAPS: "True"
OPENVPNMONITOR_DEFAULT_MAPSHEIGHT: 500
OPENVPNMONITOR_DEFAULT_SITE: Test
OPENVPNMONITOR_SITES_0_ALIAS: UDP
OPENVPNMONITOR_SITES_0_HOST: dockovpn
OPENVPNMONITOR_SITES_0_NAME: UDP
OPENVPNMONITOR_SITES_0_PORT: 5555
OPENVPNMONITOR_SITES_0_SHOWDISCONNECT: "True"
9 changes: 6 additions & 3 deletions scripts/functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ function datef() {

function createConfig() {
cd "$APP_PERSIST_DIR"
CLIENT_ID="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)"
ARG1=$1
DEFAULT_ID="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)"
CLIENT_ID="${ARG1:=$DEFAULT_ID}"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I more or less did what was mentioned here. I also modified how start.sh called this function.

CLIENT_PATH="$APP_PERSIST_DIR/clients/$CLIENT_ID"
[ -d $CLIENT_PATH ] && CLIENT_PATH=${CLIENT_PATH}_1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if given path already exists it's better to return an error code. Otherwise, we will end up in a situation where we have two certificates with the same subject name (CLIENT_ID is present in generated certificate in subject field), which in its turn may lead to other problems. For instance, when we remove client with rmclient.sh we supply subject name as a parameter and certificate is revoked.


# Redirect stderr to the black hole
easyrsa build-client-full "$CLIENT_ID" nopass &> /dev/null
Expand All @@ -30,7 +33,7 @@ function createConfig() {
cd "$APP_INSTALL_PATH"
cp config/client.ovpn $CLIENT_PATH

echo -e "\nremote $HOST_ADDR 1194" >> "$CLIENT_PATH/client.ovpn"
echo -e "\nremote $HOST_ADDR ${PORT:=1194}" >> "$CLIENT_PATH/client.ovpn"

# Embed client authentication files into config file
cat <(echo -e '<ca>') \
Expand Down Expand Up @@ -87,4 +90,4 @@ EOF
cp /opt/Dockovpn_data/pki/crl.pem /etc/openvpn

cd "$APP_INSTALL_PATH"
}
}
15 changes: 12 additions & 3 deletions scripts/genclient.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

source ./functions.sh

CLIENT_PATH="$(createConfig)"
RANDOM_CLIENT_ID="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)"
CONTENT_TYPE=application/text
FILE_NAME=client.ovpn
FILE_PATH="$CLIENT_PATH/$FILE_NAME"

if (($#))
then
Expand All @@ -18,13 +17,16 @@ then
# Switch statement
case $FLAGS in
z)
CLIENT_PATH="$(createConfig $3)"
zipFiles "$CLIENT_PATH"

CONTENT_TYPE=application/zip
FILE_NAME=client.zip
FILE_PATH="$CLIENT_PATH/$FILE_NAME"
;;
zp)

CLIENT_PATH="$(createConfig $3)"
# (()) engaes arthimetic context
if (($# < 2))
then
Expand All @@ -38,10 +40,14 @@ then
fi
;;
o)
CLIENT_PATH="$(createConfig $2)"
Copy link
Contributor Author

@usmcamp0811 usmcamp0811 Aug 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and for all the other cases I moved the createConfig call to the cases and passed in the second/third optional argument which is mean to be the cert name. If its not passed the cert name will revert to the random name.

FILE_PATH="$CLIENT_PATH/$FILE_NAME"
cat "$FILE_PATH"
exit 0
;;
oz)

CLIENT_PATH="$(createConfig $2)"
zipFiles "$CLIENT_PATH" -q

FILE_NAME=client.zip
Expand All @@ -50,6 +56,9 @@ then
exit 0
;;
ozp)

CLIENT_PATH="$(createConfig $3)"
FILE_PATH="$CLIENT_PATH/$FILE_NAME"
if (($# < 2))
then
echo "$(datef) Not enough arguments" && exit 1
Expand All @@ -74,4 +83,4 @@ echo "$(datef) NOTE: After you download your client config, http server will be

{ echo -ne "HTTP/1.1 200 OK\r\nContent-Length: $(wc -c <$FILE_PATH)\r\nContent-Type: $CONTENT_TYPE\r\nContent-Disposition: attachment; fileName=\"$FILE_NAME\"\r\nAccept-Ranges: bytes\r\n\r\n"; cat "$FILE_PATH"; } | nc -w0 -l 8080

echo "$(datef) Config http server has been shut down"
echo "$(datef) Config http server has been shut down"
36 changes: 32 additions & 4 deletions scripts/start.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/bin/bash

[ ! -d $APP_PERSIST_DIR/pki ] && cp -r /build/* $APP_PERSIST_DIR/

ADAPTER="${NET_ADAPTER:=eth0}"
source ./functions.sh

mkdir -p /dev/net
Expand All @@ -10,19 +13,19 @@ if [ ! -c /dev/net/tun ]; then
fi

# Allow UDP traffic on port 1194.
iptables -A INPUT -i eth0 -p udp -m state --state NEW,ESTABLISHED --dport 1194 -j ACCEPT
iptables -A OUTPUT -o eth0 -p udp -m state --state ESTABLISHED --sport 1194 -j ACCEPT
iptables -A INPUT -i $ADAPTER -p udp -m state --state NEW,ESTABLISHED --dport $PORT -j ACCEPT
iptables -A OUTPUT -o $ADAPTER -p udp -m state --state ESTABLISHED --sport $PORT -j ACCEPT

# Allow traffic on the TUN interface.
iptables -A INPUT -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A OUTPUT -o tun0 -j ACCEPT

# Allow forwarding traffic only from the VPN.
iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -i tun0 -o $ADAPTER -s $IP_NET -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s $IP_NET -o $ADAPTER -j MASQUERADE

cd "$APP_PERSIST_DIR"

Expand Down Expand Up @@ -68,6 +71,30 @@ cd "$APP_INSTALL_PATH"
# Print app version
$APP_INSTALL_PATH/version.sh

# make the defaults of the cookiecutter.json
echo "$(cat <<eom
{
"name": "server",
"port": "${PORT:=1194}",
"protocol": "${PROTOCOL:=udp}",
"ip_base": "${IP_BASE:=10.8.0.0}",
"ip_base_mask": "${IP_BASE_MASK:=255.255.255.0}",
"dns1": "${DNS1:=208.67.222.222}",
"dns2": "${DNS2:=208.67.222.220}",
"client2client": "${CLIENT2CLIENT:=true}"
}
eom
)" > ./config/cookiecutter.json

# This will use the above defaults and not ask for user input
cookiecutter --no-input /opt/Dockovpn/config

# move the config to where it belongs
mv /opt/Dockovpn/server/server.conf /etc/openvpn/server.conf

# clean up
rm -rf /opt/Dockovpn/server

# Need to feed key password
openvpn --config /etc/openvpn/server.conf &

Expand All @@ -79,4 +106,5 @@ if [[ -n $IS_INITIAL ]]; then
./genclient.sh $@
fi


tail -f /dev/null