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

Create an ovpn admin panel login page #212

Open
rohamdousti opened this issue Jun 4, 2023 · 9 comments
Open

Create an ovpn admin panel login page #212

rohamdousti opened this issue Jun 4, 2023 · 9 comments
Labels
enhancement New feature or request

Comments

@rohamdousti
Copy link

Do you have a method for creating an admin username and password to access the OVPN management panel?

@opsdevit-nl
Copy link

opsdevit-nl commented Jun 12, 2023

I had the same question and I read in an older issue that it's being considered. Someone remarked that it's easy to add nginx in front to provide authentication. Not sure if the following details helps you at all but I'm happy so share my solution along with some critical details that come with my implemention choices.

I ended up using nginx in front as well. My problem was that I didn't want to expose the management interface of OpenVPN by running it at any interface (0.0.0.0) which makes it vulnerable so I had it running at 127.0.0.1.
For me it was no option to install nginx at the device itself, I wanted ovpn-admin and nginx both running in containers in a pod. The latest image at dockerhub is quite old so i decided to build an image myself. The next problem was that I wanted 8080 to be exposed via the pod to nginx only and that I couldn't reach the management interface at 127.0.0.1 (as it's the pods local ip) having it implemented like that. I use podman instead of docker so I figured that if I configure the gateway of the default podman network (10.88.0.1 a.k.a. host.docker.internal ) as the ip to run the management interface at ovpn-admin is able to reach it and in that way it's not publicly exposed while I can reach it from within the pod. Nginx provides basic auth (user, pass) and with that it meets my requirements.

If I can help someone out with the for all of this then let me know, I'm happy to share it.

@rohamdousti
Copy link
Author

I had the same question and I read in an older issue that it's being considered. Someone remarked that it's easy to add nginx in front to provide authentication. Not sure if the following details helps you at all but I'm happy so share my solution along with some critical details that come with my implemention choices.

I ended up using nginx in front as well. My problem was that I didn't want to expose the management interface of OpenVPN by running it at any interface (0.0.0.0) which makes it vulnerable so I had it running at 127.0.0.1. For me it was no option to install nginx at the device itself, I wanted ovpn-admin and nginx both running in containers in a pod. The latest image at dockerhub is quite old so i decided to build an image myself. The next problem was that I wanted 8080 to be exposed via the pod to nginx only and that I couldn't reach the management interface at 127.0.0.1 (as it's the pods local ip) having it implemented like that. I use podman instead of docker so I figured that if I configure the gateway of the default podman network (10.88.0.1 a.k.a. host.docker.internal ) as the ip to run the management interface at ovpn-admin is able to reach it and in that way it's not publicly exposed while I can reach it from within the pod. Nginx provides basic auth (user, pass) and with that it meets my requirements.

If I can help someone out with the for all of this then let me know, I'm happy to share it.

please explain more

@rohamdousti
Copy link
Author

I failed, I need help

@opsdevit-nl
Copy link

opsdevit-nl commented Jun 26, 2023

In order to help you out, I need to know where you're stuck.
Maybe sharing this basic example of configuration will help you out.
Please mention that in this example no secure connection is provided for nginx. If you want to use that, create at least a self signed certificate and add it to your nginx configuration.
Also, step 6 and 8 are highly depending on where your easy-rsa config resides, mounting /etc/openvpn to the container might not be what you want as well as running containers as root, latest tags etc. and make sure port 8080 is reachable from an selinux (or apparmor etc.) and firewall perspective.
You can also use systemd to add services to create the containers and pod for persistence.

Hope this gives an impression of how I solved it. It's also completely possible to get this done without the use of containers. Just install nginx locally and use 127.0.0.1 for the management interface.

  1. create a username and password
htpasswd -c /container-data/nginx/.htpasswd admin
  1. add or adjust the management interface in /etc/openvpn/server/server.conf
management 10.88.0.1 8989
  1. create a pod
podman pod create --name ovpn -p 8080:8080
  1. nginx config at /container-data/nginx/default.conf
server {
listen 8080;
server_name 127.0.0.1;

location / {
  auth_basic           "Pass";
  auth_basic_user_file /etc/nginx/.htpasswd;
  proxy_pass http://127.0.0.1:8888;
}

}
  1. start nginx container
/usr/bin/podman run --name nginx -d --pod ovpn  -v /container-data/nginx/.htpasswd:/etc/nginx/.htpasswd:ro -v /container-data/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro docker.io/nginx:latest
  1. custom ovpn container definition at ~/ovpn-container/Containerfile
FROM alpine:latest
RUN apk update && apk upgrade && apk add bash openssl curl
RUN ln -s /bin/sh /usr/bin/sh
WORKDIR /bin
COPY ovpn-admin .
ENV PATH=$PATH:/etc/openvpn/easy-rsa
CMD /bin/ovpn-admin
  1. build custom ovpn-container
cd ~/ovpn-container
podman build -t localhost:ovpn-admin Containerfile
  1. start ovpn-admin container
/usr/bin/podman run --pod ovpn -d --name ovpn-admin -v /etc/openvpn:/etc/openvpn:Z localhost:ovpn-admin ovpn-admin --listen.host=127.0.0.1 --listen.port=8888 --mgmt=main=10.88.0.1:8989 --easyrsa.index-path="/etc/openvpn/easy-rsa/pki/index.txt" --easyrsa.path="/etc/openvpn/easy-rsa" --ccd --ccd.path=/etc/openvpn/server/ccd --ovpn.server=10.88.0.1:34494
  1. go to http://your-ip-or-domain:8080/ and use the credentials created in the first step to login

@IanWardell
Copy link

Hello, Chiming in as I am working on this as well. I am trying to put nginx in front of the admin panel at http://192.168.1.97:8080/ Do you happen to have a dockerfile?

I am using Docker for this project. (management with Portainer)

What I have so far:

  • I have ovpn-admin working, with clients connecting and local access.

What I need to do:
Actually have ngnix sit in front of the admin panel .

  • Set ovpn admin to localhost:8080
  • Create ngnix container
  • set nginx correctly

@IanWardell
Copy link

The main problem I am having is that nginx (conf below) gets a 502 error when trying to proxy to the ovpn-admin ui at docker-compose ports "127.0.0.1:8888:8080"

the UI works fine when I switch to just 8888:8080 , or if I disable nginx and do 8080:8080. I just cant get nginx to proxy correctly to the ovpn-admin ui.

nginx conf:

server {
listen 8080;
server_name 127.0.0.1;

location / {
  auth_basic           "Pass";
  auth_basic_user_file /etc/nginx/.htpasswd;
  proxy_pass http://127.0.0.1:8888;
}

}

Docker-compose:

version: '3'

services:
  openvpn:
    build:
      context: .
      dockerfile: Dockerfile.openvpn
    image: openvpn:local
    command: /etc/openvpn/setup/configure.sh
    environment:
      OVPN_SERVER_NET: "192.168.100.0"
      OVPN_SERVER_MASK: "255.255.255.0"
      OVPN_PASSWD_AUTH: "true"
    cap_add:
      - NET_ADMIN
    ports:
      - "7777:1194" # for openvpn
      - "127.0.0.1:8888:8080" # for ovpn-admin because of network_mode
    volumes:
      - ./easyrsa_master:/etc/openvpn/easyrsa
      - ./ccd_master:/etc/openvpn/ccd
  ovpn-admin:
    build:
      context: .
    image: ovpn-admin:local
    command: /app/ovpn-admin
    environment:
      OVPN_DEBUG: "true"
      OVPN_VERBOSE: "true"
      OVPN_NETWORK: "192.168.100.0/24"
      OVPN_CCD: "true"
      OVPN_CCD_PATH: "/mnt/ccd"
      EASYRSA_PATH: "/mnt/easyrsa"
      OVPN_SERVER: "#HOSTNAME#:7777:tcp"
      OVPN_INDEX_PATH: "/mnt/easyrsa/pki/index.txt"
      OVPN_AUTH: "true"
      OVPN_AUTH_DB_PATH: "/mnt/easyrsa/pki/users.db"
      LOG_LEVEL: "debug"
    network_mode: service:openvpn
    volumes:
      - ./easyrsa_master:/mnt/easyrsa
      - ./ccd_master:/mnt/ccd


  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "8080:8080" # for nginx
      - "8081:8081" # for nginx
    volumes:
      - /home/machine/nginx/.htpasswd:/etc/nginx/.htpasswd:ro
      - /home/machine/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro

@IanWardell
Copy link

In this case, I figured out ovpn-admin was still running on the container but at 8080, even when the dockerfile specified " - "127.0.0.1:8888:8080" # for ovpn-admin because of network_mode
"

My new nginx conf: looks like:

server {
listen 8080;
server_name 127.0.0.1;

location / {
  auth_basic           "Pass";
  auth_basic_user_file /etc/nginx/.htpasswd;
  proxy_pass http://ovpn-admin-openvpn-1:8080;
}

}

the docker-compose for ovpn /ovpn admin looks like

version: '3'

services:
  openvpn:
    build:
      context: .
      dockerfile: Dockerfile.openvpn
    image: openvpn:local
    command: /etc/openvpn/setup/configure.sh
    environment:
      OVPN_SERVER_NET: "192.168.100.0"
      OVPN_SERVER_MASK: "255.255.255.0"
      OVPN_PASSWD_AUTH: "true"
    cap_add:
      - NET_ADMIN
    ports:
      - "7777:1194" # for openvpn
      - "127.0.0.1:8888:8080" # for ovpn-admin because of network_mode - dnw-127.0.0.1:8888
    volumes:
      - ./easyrsa_master:/etc/openvpn/easyrsa
      - ./ccd_master:/etc/openvpn/ccd
  ovpn-admin:
    build:
      context: .
    image: ovpn-admin:local
    command: /app/ovpn-admin
    environment:
      OVPN_DEBUG: "true"
      OVPN_VERBOSE: "true"
      OVPN_NETWORK: "192.168.100.0/24"
      OVPN_CCD: "true"
      OVPN_CCD_PATH: "/mnt/ccd"
      EASYRSA_PATH: "/mnt/easyrsa"
      OVPN_SERVER: "##HOSTNAME###:7777:tcp"
      OVPN_INDEX_PATH: "/mnt/easyrsa/pki/index.txt"
      OVPN_AUTH: "true"
      OVPN_AUTH_DB_PATH: "/mnt/easyrsa/pki/users.db"
      LOG_LEVEL: "debug"
    network_mode: service:openvpn
    volumes:
      - ./easyrsa_master:/mnt/easyrsa
      - ./ccd_master:/mnt/ccd



the docker-compose for nginx looks like

version: '3'

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "8080:8080" # for nginx
      - "8081:8081" # for nginx
    volumes:
      - /home/machine/nginx/.htpasswd:/etc/nginx/.htpasswd:ro
      - /home/machine/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro


Note the other 8081 port was to test the nginx page

@Mcrich23
Copy link

Mcrich23 commented Aug 2, 2023

Got this to work:

        location /vpn/ {
            auth_basic           "Administrator’s Area";
            auth_basic_user_file /etc/nginx/.htpasswd-vpn;

            # Disable caching of credentials
            add_header Cache-Control "no-store, private, no-cache, must-revalidate, max-age=0";
            add_header Pragma "no-cache";
            add_header Expires "Thu, 01 Jan 1970 00:00:00 GMT";

            proxy_pass http://localhost:8083/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_redirect http://localhost:8083/ /vpn;
        }

@pashcovich pashcovich added the enhancement New feature or request label Dec 15, 2023
@majkel-hyggio
Copy link

I came up to this solution, resulting the web UI admin panel being accessible only for specific users from inside the VPN network and management port 8989 not being accessible from the VPN network.

changes made:

docker-compose.yaml





    ports:
      - 1194:1194/udp # for openvpn
#      - "127.0.0.1:9999:9999" # for ovpn-admin because of network_mode
    networks:
      vpn:
        ipv4_address: 10.99.0.2

## ovpn admin container     
      OVPN_LISTEN_PORT: "9999"
#      OVPN_LISTEN_HOST: "127.0.0.1"
      OVPN_MGMT: "10.99.0.2:8989"
#    network_mode: service:openvpn
    ports:
     - 9999:9999
    networks:
      vpn:
        ipv4_address: 10.99.0.3
    volumes:
      - ./easyrsa_master:/mnt/easyrsa
      - ./ccd_master:/mnt/ccd


networks:
  vpn:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 10.99.0.0/24
          gateway: 10.99.0.1
 

This allows to access the web admin panel only through nginx proxy, not from the VPN network

To disable the possibility of access the management port of VPN from inside the VPN network (if some will add 10.99.0.2 IP to routing table somehow).
setup/config.sh




#exclude 10.99.0.2 from NATing
iptables -t nat -I POSTROUTING 1 -d 10.99.0.2 -j RETURN
iptables -t nat -D POSTROUTING -s ${OVPN_SRV_NET}/${OVPN_SRV_MASK} ! -d ${OVPN_SRV_NET}/${OVPN_SRV_MASK} -j MASQUERADE || true
iptables -t nat -A POSTROUTING -s ${OVPN_SRV_NET}/${OVPN_SRV_MASK} ! -d ${OVPN_SRV_NET}/${OVPN_SRV_MASK} -j MASQUERADE
# add reject rule from VPN network to interface 10.99.0.2 inside the docker
iptables -A INPUT -i tun0 -d 10.99.0.2 -j REJECT


##end line
openvpn --config /etc/openvpn/openvpn.conf --client-config-dir /etc/openvpn/ccd --port 1194 --proto udp --management **10.99.0.2** 8989

Use an additional webserver as a proxy, being accessible only from a VPN network. Port 443 to the VPN server accessible only from that additional proxy.

strong username + password as basic auth on nginx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants