Based on kylemanna/docker-openvpn & zhaow-de/pam-keycloak-oidc. Additional documentation can be found on the respective repositories.
Disclaimer : I'm not an OpenVPN/OAuth expert, therefore this project might not respect the best practices. Use it at your own risk.
This example will use the following paths and variables:
/srv/openvpnfor the location on the host machine of OpenVPN configuration files that will be mounted on the container as a volume.10.10.100.0/24for the network range used for VPN clients10.10.1.1for the DNS servervpn.domain.localfor the public domain name
docker build -t <image_name> .
Keycloak will be used as an example.
-
Create a new Role at Keycloak, e.g.
demo-pam-authentication. (Assuming the server is athttps://keycloak.example.com) -
Create a new Client Scope, e.g.
pam_roles:- Protocol:
openid-connect - Display On Consent Screen:
OFF - Include in Token Scope:
ON - Mapper:
- Name: e.g.
pam roles - Mapper Type:
User Realm Role - Multivalued:
ON - Token Claim Name:
pam_roles(the name of the Client Scope) - Claim JSON Type:
String - Add to ID token:
OFF - Add to access token:
ON - Add to userinfo:
OFF
- Name: e.g.
- Scope:
- Effective Roles:
demo-pam-authentication(the name of the Role)
- Effective Roles:
- Protocol:
-
Create a new Keycloak Client:
- Client ID:
demo-pam(or whatever valid client name) - Enabled:
ON - Consent Required:
OFF - Client Protocol:
openid-connect - Access Type:
confidential - Standard Flow Enabled:
ON - Implicit Flow Enabled:
OFF - Direct Access Grants Enabled:
ON - Service Accounts Enabled:
OFF - Authorization Enabled:
OFF - Valid Redirect URIs:
urn:ietf:wg:oauth:2.0:oob - Fine Grain OpenID Connect Configuration:
- Access Token Signature Algorithm: e.g.
RS256
- Access Token Signature Algorithm: e.g.
- Client Scopes:
- Assigned Default Client Scopes:
pam_roles
- Assigned Default Client Scopes:
- Scope:
- Full Scope Allowed:
OFF - Effective Roles:
demo-pam-authentication
- Full Scope Allowed:
- Client ID:
-
Assign the role
demo-pam-authenticationto relevant users. A common practice is to assign the role to a Group, then make the relevant users join that group.
-
Initialize the OpenVPN server configuration.
docker run -v /srv/openvpn:/etc/openvpn --rm <image_name> ovpn_genconfig -s 10.10.100.0/24 -n 10.10.1.1 -u udp://vpn.domain.local -
Intialize the PKI
docker run -v /srv/openvpn:/etc/openvpn --rm -it <image_name> ovpn_initpki nopass
Get the OpenVPN client configuration.
docker run -v /srv/openvpn:/etc/openvpn --rm <image_name> ovpn_getclient > client.ovpn
docker run -v /srv/openvpn:/etc/openvpn <image_name>
- This image is designed to use solely an OIDC authentication and does not provide certificates or keys for clients.
- The server identity is checked with the CA certificate hardcoded in the client configuration.
- TLS keys are used to negotiate a secured channel.
- The OIDC requests are made through a PAM module.
- A modified version of zhaow-de/pam-keycloak-oidc is used, available at SekoiaLab/pam-keycloak-oidc.