{"id":17858601,"url":"https://github.com/vzakharchenko/l2tp-ipsec-radius-docker","last_synced_at":"2025-07-27T22:32:36.454Z","repository":{"id":82218184,"uuid":"328348595","full_name":"vzakharchenko/l2tp-ipsec-radius-docker","owner":"vzakharchenko","description":"L2TP IpSec Server with Radius and Radsec","archived":false,"fork":false,"pushed_at":"2021-05-24T18:08:06.000Z","size":2385,"stargazers_count":9,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-19T14:58:14.983Z","etag":null,"topics":["docker","ipsec","keycloak","radius","radius-tls","radsec"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vzakharchenko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-10T09:42:40.000Z","updated_at":"2022-09-23T10:50:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"0fce890e-e496-42b7-9561-280d723fb669","html_url":"https://github.com/vzakharchenko/l2tp-ipsec-radius-docker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzakharchenko%2Fl2tp-ipsec-radius-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzakharchenko%2Fl2tp-ipsec-radius-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzakharchenko%2Fl2tp-ipsec-radius-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzakharchenko%2Fl2tp-ipsec-radius-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vzakharchenko","download_url":"https://codeload.github.com/vzakharchenko/l2tp-ipsec-radius-docker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227732303,"owners_count":17811362,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","ipsec","keycloak","radius","radius-tls","radsec"],"created_at":"2024-10-28T05:22:22.771Z","updated_at":"2024-12-03T02:59:21.331Z","avatar_url":"https://github.com/vzakharchenko.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Docker image with L2TP (IpSec, RadSec) server including routing and port forwarding\n![l2tp-ipsec-radius-docker amd64, arm/v7, arm64](https://github.com/vzakharchenko/l2tp-ipsec-radius-docker/workflows/l2tp-ipsec-radius-docker%20amd64,%20arm/v7,%20arm64/badge.svg?branch=main)\n\n## Description\nAccess private network from the internet, support port forwarding from private network to outside via cloud.\n\n[GitHub Project](https://github.com/vzakharchenko/l2tp-ipsec-radius-docker)\n\n## Example\n![](https://github.com/vzakharchenko/l2tp-ipsec-radius-docker/blob/main/img/l2tpKeycloakWithRouting.png?raw=true)\n\n## Installation\n[create /opt/config.json](#configjson-structure)\n```\nsudo apt-get update \u0026\u0026 sudo apt-get install -y curl\ncurl -sSL https://raw.githubusercontent.com/vzakharchenko/l2tp-ipsec-radius-docker/main/ubuntu.install| bash\n```\n\n\n## Features\n - Docker image\n - Keycloak authentication and authorization\n - Radius client\n - RadSec protocol (Radius over TLS)\n - IpSec\n - [Management routing  and portforwarding using json file](#configjson-structure)\n - [Connect to LAN from the internet](#connect-to-lan-from-the--internet)\n - [Port forwarding](#port-forwarding)\n - [Connect multiple networks](#connect-multiple-networks)\n - [Automatic installation(Ubuntu)](#automatic-cloud-installation)\n - [Manual Installation steps (Ubuntu)](#manual-cloud-installationubuntu)\n - [Deny user access to VPN](#deny-user-access-to-vpn)\n\n## config.json structure\n\n```json\n{\n   \"radsec\":{\n      \"privateKey\": RADSEC_PRIVATE_KEY,\n      \"certificateFile\": RADSEC_CERTIFICATE_FILE,\n      \"CACertificateFile\": RADSEC_CA_CERTIFICATE_FILE,\n      \"certificateKeyPassword\": RADSEC_PRIVATE_KEY_PASSWORD\n   },\n   \"keycloak\":{\n      \"json\":KEYCLOAK_JSON\n   },\n   \"radius\":{\n      \"protocol\":RADIUS_PROTOCOL\n   },\n   \"authorizationMap\":{\n      \"roles\":{\n         KEYCLOAK_ROLE:{\n            \"routes\":ROUTING_TABLE,\n            \"forwarding\":[{\n               \"sourceIp\":APPLICATION_IP,\n               \"sourcePort\":APPLICATION_PORT,\n               \"externalIP\":REMOTE_IP,\n               \"externalPort\":REMOTE_PORT\n            }\n            ]\n         }\n      }\n   },\n   \"ipsec\":{\n      \"secret\":IPSEC_SHARED_SECRET\n   }\n}\n```\nWhere\n- **RADSEC_PRIVATE_KEY** ssl privateKey\n- **RADSEC_CERTIFICATE_FILE** ssl private certificate\n- **CACertificateFile** ssl CA certificate\n- **certificateKeyPassword** privateKey password\n- **KEYCLOAK_JSON** [Keycloak.json](#configure-keycloak)\n- **RADIUS_PROTOCOL** Radius protocol. Supported pap,chap and mschap-v2. If used RadSec(Radius over TLS) then better to use PAP, otherwise mschap-v2\n- **APPLICATION_IP** service IP behind NAT (port forwarding)\n- **APPLICATION_PORT** service PORT behind NAT (port forwarding)\n- **REMOTE_IP**  Remote Ip\n- **REMOTE_PORT**  port accessible from the internet (port forwarding)\n- **ROUTING_TABLE**  ip with subnet for example 192.168.8.0/24\n- **KEYCLOAK_ROLE**  Role assigned to user\n- **IPSEC_SHARED_SECRET**  Ipsec shared secret\n\n## Installation [Keycloak-Radius-plugin](https://github.com/vzakharchenko/keycloak-radius-plugin)\n- [Release Setup](https://github.com/vzakharchenko/keycloak-radius-plugin#release-setup)\n- [Docker Setup](https://github.com/vzakharchenko/keycloak-radius-plugin/blob/master/docker/README.md)\n- [Manual Setup](https://github.com/vzakharchenko/keycloak-radius-plugin#manual-setup)\n\n## Configure Keycloak\n1. Create Realm with Radius client\n![](/img/VPN1.png)\n![](/img/VPN2.png)\n2. Create OIDC client to Radius Realm\n![](/img/VPN3.png)\n3. Enable Service Accounts for OIDC client\n![](/img/VPN4.png)\n4. Add role \"Radius Session Role\" to Service Accounts\n![](/img/VPN5.png)\n5. Download Keycloak.json\n![](/img/VPN6.png)\n6. add keycloak.json to config.json\n```json\n{\n  \"radsec\": {\n    \"privateKey\": RADSEC_PRIVATE_KEY,\n    \"certificateFile\": RADSEC_CERTIFICATE_FILE,\n    \"CACertificateFile\": RADSEC_CA_CERTIFICATE_FILE,\n    \"certificateKeyPassword\": RADSEC_PRIVATE_KEY_PASSWORD\n  },\n  \"keycloak\": {\n    \"json\": {\n        \"realm\": \"VPN\",\n        \"auth-server-url\": \"http://keycloak/auth/\",\n        \"ssl-required\": \"external\",\n        \"resource\": \"vpn-client\",\n        \"credentials\": {\n            \"secret\": \"vpn-client\"\n         },\n        \"confidential-port\": 0\n    }\n  },\n  \"radius\": {\n    \"protocol\":\"pap\"\n  },\n  \"ipsec\":{\n     \"secret\":\"123456\"\n  }\n}\n```\n7. create private key, certificate  and CA certificate : RADSEC_PRIVATE_KEY ,  RADSEC_CERTIFICATE_FILE,\n\n\n## Examples\n\n- Run Keycloak-radius-plugin in Docker\n```\ndocker run -p 8090:8080 -e JAVA_OPTS=\"-Dkeycloak.profile.feature.scripts=enabled -Dkeycloak.profile.feature.upload_scripts=enabled -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true\" -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -v `pwd`/examples:/examples  -e KEYCLOAK_IMPORT=/examples/realm-export.json   vassio/keycloak-radius-plugin\n```\n| User      | Password   |  Role1           | Role2             |\n|:----------|:-----------|:-----------------|:-----------------|\n| user      | user       | X                | X                |\n| user1     | user1      | X                | -                |\n| user2     | user2      | -                | X                |\n| user3     | user3      | -                | -                |\n\n### Connect to LAN from the  internet\n\n![](https://github.com/vzakharchenko/l2tp-ipsec-radius-docker/blob/main/img/l2tpRoutingKeycloak.png?raw=true)\n- **user1** - router with subnet 192.168.88.0/24 behind NAT ![](/img/Role1.png)  ![](/img/User1.png)  ![](/img/resetPassword.png)\n- **user2** - user who has access to subnet 192.168.88.0/24 from the Internet ![](/img/User2.png)  ![](/img/resetPassword.png)\n```json\n{\n   \"radsec\":{\n      \"privateKey\":\"RADSEC_PRIVATE_KEY\",\n      \"certificateFile\":\"RADSEC_CERTIFICATE_FILE\",\n      \"CACertificateFile\":\"RADSEC_CA_CERTIFICATE_FILE\",\n      \"certificateKeyPassword\":\"RADSEC_PRIVATE_KEY_PASSWORD\"\n   },\n   \"keycloak\":{\n      \"json\":{\n         \"realm\":\"VPN\",\n         \"auth-server-url\":\"http://\u003cIP\u003e:8090/auth/\",\n         \"ssl-required\":\"external\",\n         \"resource\":\"vpn-client\",\n         \"credentials\":{\n            \"secret\":\"vpn-client\"\n         },\n         \"confidential-port\":0\n      }\n   },\n   \"radius\":{\n      \"protocol\":\"pap\"\n   },\n   \"authorizationMap\":{\n      \"roles\":{\n         \"Role1\":{\n            \"routing\":[\n               {\n                  \"route\":\"192.168.88.0/24\"\n               }\n            ]\n         }\n      }\n   },\n   \"ipsec\":{\n      \"secret\":\"123456\"\n   }\n}\n```\n\n\n### Port forwarding\n![](https://github.com/vzakharchenko/l2tp-ipsec-radius-docker/blob/main/img/l2tpKeycloakWithRouting.png?raw=true)\n- **user** - router with subnet 192.168.88.0/24 behind NAT. ![](/img/Role1.png)  ![](/img/User1.png)  ![](/img/resetPassword.png)\n- Subnet contains service http://192.168.8.254:80 which is available at from http://195.138.164.211:9000\n\n```json\n{\n   \"radsec\":{\n      \"privateKey\":\"RADSEC_PRIVATE_KEY\",\n      \"certificateFile\":\"RADSEC_CERTIFICATE_FILE\",\n      \"CACertificateFile\":\"RADSEC_CA_CERTIFICATE_FILE\",\n      \"certificateKeyPassword\":\"RADSEC_PRIVATE_KEY_PASSWORD\"\n   },\n   \"keycloak\":{\n      \"json\":{\n         \"realm\":\"VPN\",\n         \"auth-server-url\":\"http://\u003cHOST_IP\u003e:8090/auth/\",\n         \"ssl-required\":\"external\",\n         \"resource\":\"vpn-client\",\n         \"credentials\":{\n            \"secret\":\"vpn-client\"\n         },\n         \"confidential-port\":0\n      }\n   },\n   \"radius\":{\n      \"protocol\":\"pap\"\n   },\n   \"authorizationMap\":{\n      \"roles\":{\n         \"Role1\":{\n            \"forwarding\":[\n               {\n                  \"sourceIp\":\"192.168.88.1\",\n                  \"sourcePort\":\"80\",\n                  \"destinationPort\":9000\n               }\n            ]\n         }\n      }\n   },\n   \"ipsec\":{\n      \"secret\":\"123456\"\n   }\n}\n```\n### connect multiple networks\n![](https://github.com/vzakharchenko/l2tp-ipsec-radius-docker/blob/main/img/l2tpKeycloakWithRoutingMany.png?raw=true)\n- **user1** - router with subnet 192.168.88.0/24 behind NAT. Subnet contains service http://192.168.88.254:80 which is available at from http://195.138.164.211:9000 ![](/img/Role1.png)  ![](/img/User1.png)  ![](/img/resetPassword.png)\n- **user2** - router with subnet 192.168.89.0/24 behind NAT. ![](/img/Role2.png)  ![](/img/User2.png)  ![](/img/User2Role.png)  ![](/img/resetPassword.png)\n- **user3** - user who has access to subnets 192.168.88.0/24 and 192.168.89.0/24 from the Internet  ![](/img/User2.png)  ![](/img/resetPassword.png)\n```json\n{\n   \"radsec\":{\n      \"privateKey\":\"RADSEC_PRIVATE_KEY\",\n      \"certificateFile\":\"RADSEC_CERTIFICATE_FILE\",\n      \"CACertificateFile\":\"RADSEC_CA_CERTIFICATE_FILE\",\n      \"certificateKeyPassword\":\"RADSEC_PRIVATE_KEY_PASSWORD\"\n   },\n   \"keycloak\":{\n      \"json\":{\n         \"realm\":\"VPN\",\n         \"auth-server-url\":\"http:/\u003cHOST_IP\u003e:8090/auth/\",\n         \"ssl-required\":\"external\",\n         \"resource\":\"vpn-client\",\n         \"credentials\":{\n            \"secret\":\"vpn-client\"\n         },\n         \"confidential-port\":0\n      }\n   },\n   \"radius\":{\n      \"protocol\":\"pap\"\n   },\n   \"authorizationMap\":{\n      \"roles\":{\n         \"Role1\":{\n            \"forwarding\":[\n               {\n                  \"sourceIp\":\"192.168.88.254\",\n                  \"sourcePort\":\"80\",\n                  \"destinationPort\":9000\n               }\n            ],\n            \"routing\":[\n               {\n                  \"route\":\"192.168.88.0/24\"\n               }\n            ]\n         },\n         \"Role2\":{\n            \"routing\":[\n               {\n                  \"route\":\"192.168.89.0/24\"\n               }\n            ]\n         }\n      }\n   },\n   \"ipsec\":{\n      \"secret\":\"123456\"\n   }\n}\n```\n\n\n## Troubleshooting\n1. Viewing logs in docker container:\n```\ndocker logs l2tp-ipsec-radius-docker -f\n```\n2. print routing tables\n```\ndocker exec l2tp-ipsec-radius-docker bash -c \"ip route\"\n```\n3. print iptable rules\n```\ndocker exec l2tp-ipsec-radius-docker bash -c \"iptables -S\"\n```\n\n\n## Cloud Installation\n### Automatic cloud installation\n[create /opt/config.json](#configjson-structure)\n```\nsudo apt-get update \u0026\u0026 sudo apt-get install -y curl\ncurl -sSL https://raw.githubusercontent.com/vzakharchenko/l2tp-ipsec-radius-docker/main/ubuntu.install -o ubuntu.install\nchmod +x ubuntu.install\n./ubuntu.install\n```\n\n### Deny user access to VPN\n\n- create client/realm role and add attribute:\n```\nREJECT_Connect-Info=L2TP\n```\n![](./img/RejectRole.png)\n\n- assign a role to a user and after that the user will always be rejected\n\n### Manual Cloud Installation(Ubuntu)\n\n1. install all dependencies\n```\nsudo apt-get update \u0026\u0026 sudo apt-get install -y iptables git iptables-persistent nodejs linux-modules-extra-$(uname -r)\n```\n2. install docker\n```\nsudo apt-get remove docker docker.io containerd runc\nsudo curl -sSL https://get.docker.com | bash\nsudo groupadd docker\nsudo usermod -aG docker $USER\nnewgrp docker\n```\n\n3. Configure host machine\n```\nsysctl -w net.ipv4.ip_forward=1\nsysctl -w net.netfilter.nf_conntrack_helper=1\nsudo echo \"net.ipv4.ip_forward=1\"\u003e/etc/sysctl.conf\nsudo echo \"net.netfilter.nf_conntrack_helper=1\"\u003e/etc/sysctl.conf\n```\n4. [create /opt/config.json](#configjson-structure)\n\n5. start docker image\n\n```\nexport CONFIG_PATH=/opt/config.json\ncurl -sSL https://raw.githubusercontent.com/vzakharchenko/docker-l2tp-port-forwarding/main/l2tp-js/generateDockerCommands.js -o generateDockerCommands.js\n`node generateDockerCommands.js`\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvzakharchenko%2Fl2tp-ipsec-radius-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvzakharchenko%2Fl2tp-ipsec-radius-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvzakharchenko%2Fl2tp-ipsec-radius-docker/lists"}