Users open Clavister OneConnect, sign in with their normal AD account in a browser, and the VPN comes up. The firewall keeps no VPN users and no VPN passwords. Membership of one AD group decides who may connect.
This guide uses certificates from a small CA that you make on the IdAuth host. Every client PC gets this CA, and the IdAuth host serves a revocation list (CRL) that the PCs check. The firewall forwards the sign-in port, and port 80 for the CRL, to the IdAuth host.
Which setup? Use this one when you must use your own CA. If the firewall can get a Let’s Encrypt certificate, use How to - Authenticate OneConnect users with IdAuth on Linux and Let’s Encrypt instead. It is simpler: client PCs then need no CA. Both setups need TCP port 80 free on the firewall’s outside address, and public DNS names. Here, port 80 serves the CRL that client PCs check. This is one of four guides. The overview, How to - Authenticate OneConnect users with Clavister IdAuth on-premises, compares all four setups.
IdAuth is Clavister’s name for PhenixID Authentication Services; the product screens say PhenixID. In this guide, “the firewall” is your Clavister NetWall. “Reference setup” at the end lists the versions this was tested with.
One Linux host does all the IdAuth-side work: IdAuth itself, the certificates and the CRL, the reverse proxy, and the firewall upload. This guide calls it the IdAuth host.
Read this first
Three things must be right in this setup. The scripts handle all three. You only need to know they exist, so that you do not undo them.
- The firewall reads IdAuth's discovery document through a small reverse proxy in front of IdAuth, not from the IdAuth listener. Step 5.
- OneConnect on Windows checks certificate revocation. It refuses a certificate with no CRL. Step 1 makes a CRL and serves it. Step 6 lets clients on the internet reach it.
- The firewall matches plain group names. AD gives DNs, so IdAuth sends plain names. Step 4 sets that.
This guide does not cover these cases. Stop here and get help from your Clavister partner:
- port 80, 443 or PROXY_PORT on the firewall's outside address is already in use (for example by a web server), or old-style IP Rules or rule folders use those ports;
- the firewall already runs a OneConnect server;
- the firewall is an HA pair;
- the domain controller has no LDAPS.
Words you will meet:
| Word | Meaning here |
|---|---|
| Discovery document | A JSON page on IdAuth that tells the firewall where the sign-in page and the signing keys are |
| OIDC | OpenID Connect: the sign-in protocol between OneConnect, the firewall and IdAuth |
| Reverse proxy | A server that takes a web request and passes it on to another server |
| Relying party | The thing that asks IdAuth to sign a user in. Here: OneConnect and the firewall |
| Tenant | A short word in every IdAuth URL. You choose it |
| Claim | One field in the sign-in token, for example the user's groups |
| CRL | A list of revoked certificates, published by the CA on a web address |
| DN | An AD name written as a path, for example CN=VPN_Employees,CN=Users,DC=example,DC=com |
Fill in the sheet
The scripts. Download idauth-oidc-scripts-linux.zip and unpack it. It holds the scripts folder that this guide uses. The numbers in the script names are not the step numbers.
Most values below are used in more than one place. Fill in everything now except WAN_IF and LAN_IF: “Before you start” has you run the show commands of step 6, and check 2 shows them. On a cloud firewall a name can look like tap1a2b3c4d-5e.
In PowerShell, in the folder that holds scripts, make your own copy of the sheet:
copy scripts\sheet-example-own-ca.txt scripts\sheet.txt
notepad scripts\sheet.txt
Write your values from the table below into sheet.txt, and save it. Do this before you copy the folder to the IdAuth host. Steps 5 and 6 read the sheet with fill-sheet.py. It refuses a value that is missing, has a space, or is still an example (the public example addresses or example.com). It cannot check that a value such as 10.0.0.20 or If1 is right for your network: check those yourself.
In the rest of this guide, a name in capitals means “your value from the sheet”. Replace it before you press Enter. A name in front of = in a command, such as ORG= or IDAUTH_HOST=, stays as it is; replace only the value after =.
| Name | Example | What it is |
|---|---|---|
| VPN_NAME | vpn.example.com | The name users connect to |
| FW_OUTSIDE_IP | 203.0.113.10 | The public address users reach the firewall on. If a router or a cloud security group sits in front of the firewall, it is that device's public address |
| FW_MGMT_IP | 10.0.0.1 | The firewall address the IdAuth host reaches, for SSH. Usually its address on LAN_IF |
| FW_ADMIN | admin | The firewall admin account |
| WAN_IF | If1 | The firewall's outside interface, as the firewall names it |
| LAN_IF | If2 | The firewall's inside interface. DC_IP, LAN_NET and IDAUTH_IP must be behind it |
| IDAUTH_NAME | idauth.example.com | The IdAuth name. Outside it resolves to FW_OUTSIDE_IP, inside to IDAUTH_IP |
| IDAUTH_IP | 10.0.0.20 | The IdAuth host |
| PROXY_PORT | 9446 | The port of the reverse proxy. Not 8443: IdAuth uses 8443 on the same host. Not 443 or 80: OneConnect and the CRL need them. If a router or cloud security group sits in front of the firewall, open this port there too |
| IDAUTH_URL | https://idauth.example.com:9446 | https://IDAUTH_NAME:PROXY_PORT. The firewall and the user's browser both use it |
| TENANT | corp | A short word, letters only. Becomes part of every OIDC URL |
| DC_IP | 10.0.0.10 | The domain controller, and the DNS server VPN users get |
| DOMAIN_DN | DC=example,DC=com | Your AD domain as a DN |
| SVC_DN | CN=svc-idauth,CN=Users,DC=example,DC=com | The service account IdAuth reads AD with |
| VPN_GROUP | VPN_Employees | The AD group whose members may use the VPN. The plain name, no spaces, never a DN |
| LAN_NET | 10.0.0.0/24 | The inside network VPN users may reach |
| VPN_POOL | 10.0.99.10-10.0.99.100 | Addresses for VPN clients. Must not overlap any network the firewall routes |
| VPN_INNER | 10.0.99.1 | The firewall's own address in the pool's network, but not inside the pool range. Example: pool 10.0.99.10-10.0.99.100, inner 10.0.99.1 |
| USERS_SRC | 198.51.100.0/24 | Where users may reach the sign-in page from. Users at home need 0.0.0.0/0 (the whole internet). For the first test use 0.0.0.0/0, and narrow it when step 7 works: a phone hotspot has the mobile carrier's address, which a narrow range does not hold. It limits the sign-in page and the CRL address; OneConnect on 443 answers everyone |
| VPN_PORTS | 443,445 | The TCP ports VPN users may reach inside |
| SYSLOG_IP | 10.0.0.20 | Where the firewall sends its log. The IdAuth host is fine |
| TEST_USER | jdoe | A user in VPN_GROUP, for the tests |
| OTHER_USER | asmith | A user not in VPN_GROUP, for the refusal test |
Before you start
You need every item below. If one is missing, a later step fails.
Two machines. An admin PC on the inside, and a test PC on the internet that does not use your inside DNS (a laptop on a phone hotspot is enough). Step 7 needs both at the same time.
The firewall CLI. Many commands in this guide run on the firewall’s command line. Open it from your admin PC, in PowerShell: ssh FW_ADMIN@FW_MGMT_IP, or the address you manage the firewall on. The first time, type yes to the question about the key. The prompt ends in :/>. This guide writes Device:/>; your firewall shows its own name there. If SSH is refused, SSH management is not on for your PC: ask whoever set up the firewall.
A router in front of the firewall. If another router or a cloud security group sits in front of it, that device must pass TCP 80 (the CRL), TCP and UDP 443 (OneConnect) and TCP PROXY_PORT (the sign-in page) to the firewall.
Look at step 6 now. Checks 2 to 5 of step 6 start with show commands, which change nothing. Run only these show commands now, and write down what checks 3 and 4 show; do not type the set lines yet. If check 5 finds port 80, 443 or PROXY_PORT taken, stop: this guide does not cover it.
Firmware. On the firewall CLI, about must show cOS Core 15.00.06 or later. This guide was tested on 15.00.06.10. The per-interface OneConnect certificate came in 15.00.02. Upgrade first.
Licences. IdAuth needs its licence file (license.p12) to open its ports. NetWall needs SSL VPN in its licence. On the firewall CLI, license must show a Max SSLVPN Tunnels line above 0.
IdAuth media from Clavister. The container image tar and license.p12. Put both in the scripts folder.
The IdAuth host (IDAUTH_IP). A Linux server with Docker. Debian 13 with 2 vCPU, 6 GB RAM and 20 GB disk is enough. Give it a fixed address, with this firewall as its default gateway: sign-in requests reach the host with the users’ own addresses, and the answers must go back through this firewall. The host also needs outbound HTTP and HTTPS to the internet, for the apt lines below and the test tools in step 5. If you install Debian, leave the root password empty (then your own account gets sudo) and tick SSH server.
From your PC, in PowerShell, in the folder that holds scripts, copy it to the host and log in. <you> is your account on the host:
scp -r .\scripts <you>@IDAUTH_IP:
ssh <you>@IDAUTH_IP
Then, on the host:
sudo -i
cd /home/<you>/scripts
apt update && apt install -y openssl curl python3 python3-venv bind9-host cron
echo "IDAUTH_IP IDAUTH_NAME" >> /etc/hosts
getent hosts IDAUTH_NAME
If docker --version says command not found, also run apt install -y docker.io. The last line must print IDAUTH_IP: the host must find its own IdAuth name. To fix a wrong line: nano /etc/hosts (save with Ctrl+O and Enter, quit with Ctrl+X). Edit sheet.txt the same way. From now on, edit only this copy of sheet.txt, on the IdAuth host.
In this guide, “as root on the IdAuth host” means the window above: after sudo -i, in the scripts folder. Work as root, not with sudo in front of each command: sudo drops the NAME=value settings that steps 1 and 2 put in front of their commands.
In AD:
- a service account svc-idauth with a password that never expires;
- the group VPN_GROUP, with TEST_USER in it as a direct member. Groups inside the group do not count;
- OTHER_USER, not in the group.
On a DC, or a PC with the AD tools, as a domain admin:
$pw = Read-Host -AsSecureString "Password for svc-idauth"
New-ADUser -Name svc-idauth -SamAccountName svc-idauth -Enabled $true `
-PasswordNeverExpires $true -AccountPassword $pw -Path "CN=Users,DOMAIN_DN"
New-ADGroup -Name VPN_GROUP -GroupScope Global -Path "CN=Users,DOMAIN_DN"
Add-ADGroupMember -Identity VPN_GROUP -Members TEST_USER
Then check them (if they exist already, only check them):
Get-ADUser svc-idauth -Properties PasswordNeverExpires | Select-Object Name, PasswordNeverExpires
Get-ADGroupMember VPN_GROUP | Select-Object -ExpandProperty SamAccountName
(Get-ADUser OTHER_USER -Properties MemberOf).MemberOf
(Get-ADUser svc-idauth).DistinguishedName
PasswordNeverExpires must be True. The group must list TEST_USER (this lists direct members only). The third command must not show VPN_GROUP. The last command prints your SVC_DN: write it into sheet.txt exactly.
On Samba AD, create them with samba-tool user create svc-idauth, samba-tool user setexpiry svc-idauth --noexpiry (or the password expires after 42 days and every sign-in fails), samba-tool group add VPN_GROUP and samba-tool group addmembers VPN_GROUP TEST_USER.
LDAPS on the DC. IdAuth reads AD over LDAPS, port 636. Check it now, as root on the IdAuth host:
openssl s_client -connect DC_IP:636 </dev/null 2>/dev/null | grep -c BEGIN
It must print 1. If not, stop here: the DC needs a certificate for LDAPS, which is a job for your AD team.
DNS, two views. At your public DNS provider, VPN_NAME and IDAUTH_NAME point to FW_OUTSIDE_IP. Inside, IDAUTH_NAME points to IDAUTH_IP. Add the inside record as its own zone, so that it does not touch the rest of your domain. On the DC at DC_IP:
# Windows DNS
Add-DnsServerPrimaryZone -Name IDAUTH_NAME -ReplicationScope Domain
Add-DnsServerResourceRecordA -ZoneName IDAUTH_NAME -Name "@" -IPv4Address IDAUTH_IP
# Samba AD
samba-tool dns zonecreate DC_IP IDAUTH_NAME -U Administrator
samba-tool dns add DC_IP IDAUTH_NAME @ A IDAUTH_IP -U Administrator
The Windows lines print nothing. Check on the IdAuth host: host IDAUTH_NAME DC_IP must answer with IDAUTH_IP.
If VPN_NAME and IDAUTH_NAME are the same name, every PC that uses this DNS gets the inside address for it. Then use OneConnect from outside the office, and run step 7 on a PC that does not use your DNS. A phone hotspot is enough.
The DC must also answer internet names (a Windows DC with forwarders does): step 6 makes it the firewall’s only DNS server. Check: host www.clavister.com DC_IP on the IdAuth host must print an address.
Time. Firewall, IdAuth host and DC on the same NTP source. The token lives 2 minutes, so a clock that is a few minutes off fails every sign-in. On the IdAuth host, timedatectl must say System clock synchronized: yes. On the firewall CLI, time shows its clock and its time zone. It must be within a minute of date on the IdAuth host; date may use another time zone, often UTC.
A backup of the firewall, first. Before you change anything on the firewall, check on the firewall CLI that nothing is pending: show -changes must say There are no changes. (more in step 6, check 1). Then, from your admin PC, in PowerShell:
scp -O FW_ADMIN@FW_MGMT_IP:config.bak fw-before-oidc.bak
Use the address you manage the firewall on, if it is not FW_MGMT_IP. Keep the file in a safe folder: it holds the firewall’s secrets. It is your way back; see “Remove it again” at the end of this guide.
SSH from the IdAuth host to the firewall. Step 6 runs from the IdAuth host. As root on it:
ssh FW_ADMIN@FW_MGMT_IP
It must show the firewall’s prompt, which ends in :/>. This guide writes Device:/>; your firewall shows its own name there. Type exit to leave. If it says Connection timed out, the firewall’s SSH management does not allow this host. Add that from the PC you manage the firewall with today, in its SSH session:
Device:/> add RemoteManagement RemoteMgmtSSH ssh_idauth Interface=LAN_IF Network=IDAUTH_IP LocalUserDatabase=AdminUsers
Device:/> activate
Device:/> commit
AdminUsers is the firewall’s own admin database. If your admins log in through RADIUS, use the database of your existing SSH line instead (show RemoteManagement). Step 7 removes this line again at the end.
activate starts the new configuration. Then commit must follow within 30 seconds, or the firewall goes back to the old one by itself. This protects you from a change that cuts off your own access. commit answers Committed changes. This pair is used every time in step 6.
A syslog receiver at SYSLOG_IP. It is where you read the firewall’s errors. For the setup and the tests this is enough. Run it as root on the IdAuth host, in a second window. Keep that window open until the end of step 7; it stops when you close it. The firewall sends nothing to it before step 6b.
python3 -u - <<'EOF' | tee -a /root/fw.log
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("0.0.0.0", 514))
while True:
print(s.recv(65535).decode(errors="replace"), flush=True)
EOF
The test PC needs OneConnect from the Microsoft Store. See Configure Clavister OneConnect for Windows towards Clavister NetWall, or Install OneConnect without Microsoft store for a PC without the Store.
Step 1 - Certificates and the CRL
As root on the IdAuth host:
ORG="Your Company" CRL_URL=http://IDAUTH_NAME/ca.crl P12PW=skip \
bash 02-make-ca.sh VPN_NAME FW_OUTSIDE_IP IDAUTH_NAME IDAUTH_IP
ORG becomes the name of your CA on every client PC; use your company name, with letters, digits and spaces only. The script also prints an Import-Certificate line: ignore it, step 7 does that. The four values at the end are in that order. P12PW=skip stops it from making a key file (idauth.p12) that this guide does not use.
The script writes to /opt/idauth-ca/:
| File | Used in |
|---|---|
| ca.crt | the firewall (step 6), every client PC (step 7) |
| vpn.crt, vpn.key | the firewall (step 6) |
| idauth.crt, idauth.key | the proxy (step 5) |
| ca.crl | the CRL web server, below |
If the output ends with a large warning NO CRL distribution point, CRL_URL was lost. Run the command again with FORCE_REISSUE=yes added in front.
ca.key can sign certificates that every client PC will trust. Anyone who gets it can pretend to be any web site to those PCs. Use this host for nothing else, and keep it patched. A company CA that already publishes a CRL is the better choice if you have one.
Serve the CRL from a folder that holds only that file:
mkdir -p /var/www/crl && cp /opt/idauth-ca/ca.crl /var/www/crl/ && chmod 644 /var/www/crl/ca.crl
cp crl-web.service /etc/systemd/system/
systemctl daemon-reload && systemctl enable --now crl-web
Check:
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1/ca.crl
openssl x509 -in /opt/idauth-ca/vpn.crt -noout -ext crlDistributionPoints
Expect 200, then a line URI:http://IDAUTH_NAME/ca.crl: the CRL address inside the certificate. It must be the address you serve.
The CRL expires after 30 days. Renew it every week with this cron file:
cat > /etc/cron.d/crl-renew <<'EOF'
0 3 * * 1 root cd /opt/idauth-ca && openssl ca -config crl-openssl.cnf -gencrl -out ca.crl && cp ca.crl /var/www/crl/ca.crl
EOF
systemctl is-active cron
The last line must print active. A minimal Debian has no cron until the apt line in “Before you start” installs it, and then the CRL is never renewed.
If the CRL expires, no client can connect until it is renewed. To see when it expires: openssl crl -in /var/www/crl/ca.crl -noout -nextupdate.
Step 2 - Install IdAuth
As root on the IdAuth host:
BIND=IDAUTH_IP bash 01-idauth-container.sh pas_7.0.2-amd64.tar license.p12
Use the real file names. BIND keeps the IdAuth listener on one address. That listener also serves the admin portal, so it must not be on every interface.
Check:
docker ps --filter name=idauth
Expect one line for idauth, with STATUS Up ... (healthy). The script itself can take several minutes the first time; it prints health: starting until IdAuth is up.
Then open https://IDAUTH_IP:8443/config/ in a browser on the inside network. Accept the certificate warning; that listener keeps its own certificate, and users never see it.
The login page may be in Swedish. To change it, press the three dots at the top right and pick English under Språk. Sign in with the product default: user phenixid, password password. Change it at once: PHENIXID at the top right > Change password.

Step 3 - Four wizards in IdAuth
All four are under Scenarios: a tab bar at the top and a list of rows on the left, each with a +. Fill in only what is listed. Leave everything else as the wizard has it. Each wizard ends with a summary: press Create there.
If this IdAuth already serves other applications, still create everything new, as below. Do not reuse an existing OpenID Provider.

3a. LDAP connection
Scenarios > Connections > LDAP > +
| Screen | Field | Value |
|---|---|---|
| Connection Name | Name | AD-LDAPS |
| Connection Details | Host, Port | DC_IP, 636 |
| Credentials | Bind DN, Password | SVC_DN, its password |
| SSL | SSL | on |
| SSL | Trust all | on. See "Before you go live" |
After the SSL screen, the wizard shows Connection status: Not tested and a blue Test connection link under it. Press it: it must say Connection status: Success (OK when you test the saved connection later). The wizard also says the account needs read and write access. Read access is enough here (a normal domain user); do not give it more.


Check SSL on the saved connection, not the wizard’s summary: USE SSL/TLS and TRUST ALL ticked.
3b. Authenticator
Scenarios > Authenticators > Dynamic Authenticator > +
| Screen | Value |
|---|---|
| Scenario | AD-Username-Password |
| Authenticator alias | uidpwd |
| Select preset | Username & Password |
| User store | AD-LDAPS |
| Search filter | leave the default, as in the third picture below |
| Search base | DOMAIN_DN. The wizard usually fills it. If not, press Choose or type it |
| User identifier | sAMAccountName |



Use the Authenticators tab. Do not use Legacy guides: it sets up a client secret, and OneConnect signs in without one.
3c. Relying party
Scenarios > OIDC > Relying party > +
| Field | Value |
|---|---|
| NAME | NetWall-OneConnect |
| CLIENT_ID | oneconnect, exactly: the scripts expect this name |
| CLIENT_PASSWORD | anything. It is not used |
| DESCRIPTION | anything |
| ALLOWED REDIRECT_URI:S | the three lines below, one per + Add |
http://127.0.0.1/oneconnect/oauth/
http://[::1]/oneconnect/oauth/
com.clavister.oneconnect://oauth/
These three come from Clavister. Use exactly these.

3d. OpenID Provider
Scenarios > OIDC > OpenID Provider > +
| Screen | Value |
|---|---|
| Scenario | NetWall-OneConnect |
| Base URL | IDAUTH_URL. No path |
| Tenant | TENANT |
| Supported scopes | openid is filled in already. Leave it |
| Claims | add the three below |
| Allowed relying party | select oneconnect. Nothing is selected by default |
| Authenticator | AD-Username-Password |
| Keystore | leave the default |

If you typed another address as Base URL, step 4 repairs it.
The three claims. For each claim: tick Show additional configuration parameters to see the field Item property name (the tick clears after every Add claim). Pick openid under Scopes (nothing is picked at first). Leave Include in id_token on. Press Add claim.
| Claim name | Item property name |
|---|---|
| groups | memberOf |
| given_name | givenName |
| family_name | sn |


Check, as root on the IdAuth host:
curl -sk https://IDAUTH_IP:8443/TENANT/.well-known/openid-configuration \
| python3 -m json.tool | grep -E '"issuer"|"groups"'
Expect an "issuer" line and a line with "groups". The issuer should be IDAUTH_URL/TENANT. If it shows 8443, go on; step 4 fixes it.
Step 4 - The settings outside the wizards
Up to seven more settings are needed. One script sets all of them. It changes only the oneconnect relying party, the OpenID Provider that allows it, and that provider’s authenticator (it adds one processing step). IdAuth is restarted, so sign-ins stop for about a minute; if other applications use this IdAuth, do it in a maintenance window.
Close every IdAuth portal tab first. An old tab can later save the old settings back.
If this IdAuth also serves other applications, first run the first line below with --dry-run added, and read every CHANGE line. Then, as root on the IdAuth host:
python3 07-idauth-fixup.py --proxy-url IDAUTH_URL
docker restart idauth
The script prints one line per setting. ok means it was already right. CHANGE means it set it. It backs up the configuration file first, and a second run says Nothing to change.
Check. Wait until docker ps shows (healthy) again, then:
curl -sk https://IDAUTH_IP:8443/TENANT/.well-known/openid-configuration | python3 -m json.tool | grep '"issuer"'
curl -sk https://IDAUTH_IP:8443/TENANT/.well-known/openid-configuration \
| python3 -m json.tool | grep -A2 code_challenge
Expect "issuer": "IDAUTH_URL/TENANT", then "S256" and nothing else in that list.
Step 5 - The reverse proxy, and the full IdAuth test
The firewall and the user’s browser both reach IdAuth through this proxy.
As root on the IdAuth host:
cp 06-idauth-proxy.py /usr/local/bin/
python3 fill-sheet.py sheet.txt idauth-proxy.service /etc/systemd/system/idauth-proxy.service
systemctl daemon-reload && systemctl enable --now idauth-proxy
journalctl -u idauth-proxy --since "-5 min"
The log must show relaying only: /TENANT/, /authentication/, /web-app/, /lang/. A line NOTE: the hop to IdAuth is not checked is normal here: the proxy and IdAuth are on the same host. The proxy passes on only the paths the sign-in needs. Everything else, the admin portal included, gets the answer 404.
Check 1:
curl -s --cacert /opt/idauth-ca/ca.crt \
https://IDAUTH_NAME:PROXY_PORT/TENANT/.well-known/openid-configuration \
| python3 -m json.tool | grep '"issuer"'
curl -sk --path-as-is -o /dev/null -w "%{http_code}\n" https://IDAUTH_NAME:PROXY_PORT/TENANT/../config/
Expect "issuer": "IDAUTH_URL/TENANT", then 404.
Check 2, the real test. It signs in as TEST_USER in a headless browser and checks the token the way the firewall will. Install it once. It takes about a minute and needs about 1 GB of disk:
python3 -m venv /opt/oidc-test
/opt/oidc-test/bin/pip install playwright requests cryptography
/opt/oidc-test/bin/playwright install --with-deps chromium
Run it. The first line asks for the test user’s password without showing it:
read -s -p "TEST_USER password: " IDAUTH_PW; export IDAUTH_PW; echo
IDAUTH_HOST=IDAUTH_NAME IDAUTH_PORT=PROXY_PORT IDAUTH_TENANT=TENANT \
IDAUTH_CA=/opt/idauth-ca/ca.crt IDAUTH_USER=TEST_USER \
/opt/oidc-test/bin/python 05-verify-oidc.py
unset IDAUTH_PW
The script finds IDAUTH_NAME through the normal name lookup. Do not add IDAUTH_IP= to this command: in this script it replaces that lookup.
Expect three PASS rows and All checks passed. The first row also shows signature OK and a groups: line such as ['VPN_Employees,Sales']. That is one string with commas in it, which is correct: the firewall splits it on the comma.
- groups: shows CN=... values: IdAuth was not restarted after step 4.
- Row 1 says FAIL no authorization code: a wrong password, TEST_USER not under the search base (3b), or a locked account.
- A row says INCONCLUSIVE: the run could not decide. Check the password and run again. It is not a pass.
Do not go to step 6 until this passes. After this point a problem is much harder to find.
Step 6 - The firewall
Step 6 runs as root on the IdAuth host: SSH to the firewall in one window, and the host’s own commands in another.
Before you run anything: five checks
The backup. You took it in “Before you start”. If anyone has changed the firewall since then, take a new one the same way. A new backup also holds the SSH line from “Before you start”; after a restore from it, delete that line again (end of step 7).
The firewall script only adds objects, and every object it adds starts with oc. It does not change interfaces, routes, existing rules or the management certificate. Checks 3 and 4 below may change two global settings; write the old values down. The script cannot know these five things. Check them in an SSH session to FW_MGMT_IP.
1. Nothing is pending.
Device:/> show -changes
It must say There are no changes. The single line One or more indexed objects have been moved. is also fine. If objects are listed, someone has unsaved work: ask them first. Then activate and commit, or throw it away with reject -all. Tell the other admins not to change anything until step 6 is done.
2. Interface names. show Interface Ethernet lists them (show Interface lists every kind of interface, most of them empty). The outside one is the one your internet line is on. Put the outside one in WAN_IF and the inside one in LAN_IF in sheet.txt. Then check the outside address object:
Device:/> show Address IP4Address InterfaceAddresses/If1_ip
Use your WAN_IF in place of If1. It must print an object. With DHCP on the outside interface (usual in a cloud), Address is 0.0.0.0 and ActiveAddress shows the real address. That is fine. If show prints no object, your outside interface is not a plain Ethernet interface with its own address object. The guide was not tested that way; get help.
3. The WebUI ports. show Settings RemoteMgmtSettings. OneConnect needs 443, and the CRL needs 80 (client PCs download it from there), even if no rule lets anyone reach the WebUI there. With the WebUI on 80, the CRL address gets the firewall’s own web page, and clients cannot connect. Move only the one that is in the way, and write down the old value:
Device:/> set Settings RemoteMgmtSettings WWWSrv_HTTPSPort=4443
Device:/> set Settings RemoteMgmtSettings WWWSrv_HTTPPort=8080
Device:/> activate
Device:/> commit
Run the first line only if WWWSrv_HTTPSPort is 443, and the second only if WWWSrv_HTTPPort is 80. Pick free ports, and not PROXY_PORT. Tell the other admins the new ports. If you reach the WebUI through a router or a cloud security group, open the new port there too. Do that before you type activate: commit must follow within 30 seconds.
4. The firewall’s own DNS. The firewall must resolve IDAUTH_NAME to IDAUTH_IP, and it must never ask a public DNS server instead. show DNS lists its servers. Write them down. Then use the DC only:
Device:/> set DNS DNSServer1=DC_IP DNSServer2="" DNSServer3=""
Device:/> activate
Device:/> commit
A second DC is fine as DNSServer2; a public server is not. With a public server in the list, the firewall can get its own outside address for IDAUTH_NAME; ping can still look right.
This changes name lookups for the whole firewall: rules with names, IPsec peers, NTP and log servers given by name, updates and the licence. If your configuration uses names, check that the DC answers them the same way as your old servers.
Then check:
Device:/> ping IDAUTH_NAME
Sending 1 4-byte ICMP ping to 10.0.0.20 from 10.0.0.1
Device:/> ping www.clavister.com
The first line of the first ping must show IDAUTH_IP. The second ping must show an address: the firewall still finds internet names. The ping answers themselves do not matter. The ping only shows that the DC answers; the real proof is oidc in 6c.
5. The outside address is free. OneConnect needs TCP and UDP 443 on FW_OUTSIDE_IP. The CRL needs TCP 80 (client PCs download it from there), and the sign-in page needs PROXY_PORT.
Device:/> show IPRule
Device:/> show IPPolicy
Device:/> show ACMEAccount
Device:/> show Interface OneConnectInterface
What to look for:
- show IPRule: on an older configuration it lists the old-style IP rules too. On a configuration made on 15.x it answers Invalid object type, which is fine.
- show IPPolicy: it lists IP policies and reverse proxy policies. On an empty rule set it prints a list of types, then There is no object of the type IPPolicy., which is fine.
- In both lists, look for entries with source interface WAN_IF or any that allow, forward (SAT) or reverse-proxy traffic to the outside address on port 80, 443 or PROXY_PORT. Services such as http, https, http-all or all_services cover those ports; for a service with another name, show Service ServiceTCPUDP <name> shows its ports. Such an entry means the port is taken, and this guide does not cover that.
- A Deny entry, such as a closing deny-all, is fine: 6c puts the new entries above it.
- show ACMEAccount must say There is no object of the type ACMEAccount. If the firewall already gets certificates from Let's Encrypt, it answers port 80 itself for that, and this guide does not cover it.
- show Interface OneConnectInterface must say There is no object of the type OneConnectInterface.
6a. The certificates
As root on the IdAuth host:
cd /opt/idauth-ca
scp -O vpn.crt FW_ADMIN@FW_MGMT_IP:certificate/oc_vpncert
scp -O vpn.key FW_ADMIN@FW_MGMT_IP:certificate/oc_vpncert
scp -O ca.crt FW_ADMIN@FW_MGMT_IP:certificate/oc_ca
cd -
Each scp asks for the firewall password. It prints nothing when it works. -O selects the SCP protocol that the firewall uses; if your scp does not know -O, leave it out.
On the firewall:
Device:/> show Certificate
Device:/> activate
Device:/> commit
show Certificate must list oc_vpncert with type Local and oc_ca with type Remote. A + in front of a name means it is not saved yet. Ignore the exit code of scp; show Certificate is the proof. Commit now, so that a reject -all in 6b cannot remove them.
6b. The objects
If you already send the firewall log to a syslog server, you may delete the oc_log line from 03-netwall-own-ca.sgs first. Then look for the firewall’s messages in your own log server, not in /root/fw.log, and leave out delete LogReceiverSyslog oc_log in “Remove it again”. Then, as root on the IdAuth host:
python3 fill-sheet.py sheet.txt 03-netwall-own-ca.sgs oidc.sgs
scp -O oidc.sgs FW_ADMIN@FW_MGMT_IP:script/oidc.sgs
fill-sheet.py prints the values that go into the firewall script. Read them once. scp prints nothing; ignore its exit code. On the firewall, script must list oidc.sgs. If scp says Permission denied, a script with that name is already on the firewall (or the password was wrong): run script -remove -name=oidc.sgs on the firewall and upload again.
On the firewall:
Device:/> script -execute -name=oidc.sgs
Device:/> activate
Device:/> commit
script -execute ends with There are no errors. when every line worked. You type activate yourself, after the script. When commit has answered, delete the file from the firewall:
Device:/> script -remove -name=oidc.sgs
It is not needed any more. With it gone, the next upload works and old values cannot run by mistake.
If a line fails, the run stops at that line and does nothing after it. Do not run the file again: it would stop at line 1 with already exists. Instead:
Device:/> reject -all
Device:/> script -remove -name=oidc.sgs
Then fix the value in sheet.txt, fill, upload and run again.
What the script creates: the log receiver oc_log, address and service objects, the OIDC provider oc_idauth, the user group oc_vpn_group, the OneConnect server oc-vpn with its own certificate and split tunnel, and five IP policies. Two of them publish PROXY_PORT (the sign-in page) and port 80 (the CRL) on the outside address to IDAUTH_IP.
6c. Rule order, then the checks
The five new policies land at the end of the rule set, below any deny-all. Move them to the top. Run these lines in exactly this order, last rule first:
Device:/> set IPPolicy oc-vpn-deny Index=1
Device:/> set IPPolicy oc-vpn-to-lan Index=1
Device:/> set IPPolicy oc-vpn-dns Index=1
Device:/> set IPPolicy oc-publish-crl Index=1
Device:/> set IPPolicy oc-publish-idauth Index=1
Device:/> activate
Device:/> commit
Each move puts a rule at the top, so the rule moved last ends up first. At the top they cannot be overridden by a broader rule of yours. They do not change your other traffic: three match only traffic from the VPN, and two match only PROXY_PORT and port 80 on the outside address, which check 5 found free.
If your rule set starts with drop rules for internet traffic (geo-blocking, block lists), keep the two oc-publish rules below them. Then do it in this order instead: show IPPolicy, note the index N of the first entry below your drop rules, run set IPPolicy oc-publish-crl Index=N and set IPPolicy oc-publish-idauth Index=N, and then only the three set IPPolicy oc-vpn lines. The check below then shows the three VPN rules, your drop rules, then oc-publish-idauth and oc-publish-crl.
Then check:
Device:/> show IPPolicy
The first five must be oc-publish-idauth, oc-publish-crl, oc-vpn-dns, oc-vpn-to-lan and oc-vpn-deny, in that order. The table shortens long names (oc-pu..., oc-vp...), so read the other columns: Allow with service oc_sv... (that is oc_svc_idauth), Allow with http, then Allow to oc_dc_dns, Allow to oc_lan_net, and Deny to all-nets.
Device:/> oidc -refresh
Device:/> oidc
Expect Status : Discovery completed and Loaded keys of 1 or more.
Device:/> userauth -privilege
Expect a line like "VPN_Employees" 13: your group name and its length. A line that starts "CN= means a DN got into the group object.
The public check. On the test PC (on the internet, not using your inside DNS), in PowerShell, first the sign-in port: Test-NetConnection IDAUTH_NAME -Port PROXY_PORT must say TcpTestSucceeded : True. False means a router or security group in front of the firewall does not pass PROXY_PORT, or the PC’s public address is not in USERS_SRC. Then the CRL:
(Invoke-WebRequest http://IDAUTH_NAME/ca.crl -UseBasicParsing).Headers['Content-Type']
It must say application/pkix-crl. text/html means the firewall’s own web page answered: check 3, the WebUI on port 80. No answer: the same causes as False above, for port 80.
Step 7 - The client
Get ca.crt from the IdAuth host. On your admin PC, in PowerShell:
scp <you>@IDAUTH_IP:/opt/idauth-ca/ca.crt .
Then put it in C:\temp on the test PC (create the folder if it is not there), and copy scripts\04-windows-client.ps1 there too. Neither file is secret. First install your CA. On the PC, in PowerShell as administrator:
Import-Certificate -FilePath C:\temp\ca.crt -CertStoreLocation Cert:\LocalMachine\Root
Its Subject column must start with CN=ORG. The PC now trusts every certificate your CA makes. Close that window. Signed in as the user who will use OneConnect, open a normal PowerShell, not as administrator: OneConnect must start as that user, to take the profile link and show the right status. Then:
cd C:\temp
powershell -ExecutionPolicy Bypass -File .\04-windows-client.ps1 -VpnName "Company VPN" `
-Server VPN_NAME -SignInName IDAUTH_NAME -SignInPort PROXY_PORT -OwnCA
-ExecutionPolicy Bypass is needed because a Windows PC does not run scripts by default. The script checks the sign-in page and must print Sign-in address https://IDAUTH_NAME:PROXY_PORT/ answers, and this PC trusts its certificate., then CRL http://IDAUTH_NAME/ca.crl answers (application/pkix-crl). Then OneConnect opens with the profile filled in. Press Save. If no profile window opens, close OneConnect completely and run the script again.

In OneConnect, pick Company VPN in the drop-down under the logo, then press Connect. Connect stays grey until a profile is picked.
A browser opens on the IdAuth sign-in page. Sign in at once as TEST_USER: the user name only, as in jdoe, and the AD password. OneConnect waits about two minutes for the sign-in (measured in the lab). If the browser shows 127.0.0.1 refused to connect after you signed in, that time had run out: press Connect again and sign in at once. The page is in Swedish: Användarnamn is the user name and Lösenord the password. The browser then shows Authentication complete. Close it.
OneConnect then shows Connected.

Check on the firewall:
Device:/> userauth -list
Expect TEST_USER, an address from VPN_POOL, interface oc-vpn, and VPN_GROUP under Privileges.
Check on the PC, in PowerShell:
Resolve-DnsName IDAUTH_NAME -Server DC_IP
Test-NetConnection DC_IP -Port 445
The first must answer with IDAUTH_IP (an extra SOA row is normal): DNS works through the VPN. The second must say TcpTestSucceeded : True if DC_IP is in LAN_NET and 445 is in VPN_PORTS. Only LAN_NET goes through the VPN; the PC’s internet traffic does not.
The refusal test. In OneConnect press Disconnect. Close every browser window, so the old sign-in is gone. Press Connect and sign in as OTHER_USER.
The browser still says Authentication complete: IdAuth accepted the password. Then OneConnect shows Connection failed and You are not authorized to log in. That is the group rule working. On the IdAuth host, grep -a user_group_disallow /root/fw.log | tail -1 shows the firewall’s reason. The file keeps older lines: the time in that line must be now, on the firewall’s clock (time). If OTHER_USER gets in, check userauth -privilege again.
The firewall log also shows oc-vpn-deny drops of Windows broadcast and multicast from connected PCs (UDP 137 and 1900, IGMP). That is normal.
Remove the SSH line if you added one in “Before you start”. Do it from your admin PC, not from the IdAuth host, whose session this line allows:
Device:/> delete RemoteManagement RemoteMgmtSSH ssh_idauth
Device:/> activate
Device:/> commit
The setup is done.
Remove it again
There are two ways back. Use one of them, not both.
The backup. It puts back the whole configuration from when you took it, the WebUI ports and DNS servers included. It also undoes every change anyone made after the backup. From your admin PC, in PowerShell, in the folder that holds fw-before-oidc.bak:
scp -O fw-before-oidc.bak FW_ADMIN@FW_MGMT_IP:
Ignore the exit code of scp. The firewall loads the file as a pending change. Then, on the firewall, activate and commit. If the backup is from after you added the SSH line, delete that line again, as at the end of step 7.
The delete list. It removes only what this guide added. From your admin PC, on the firewall, in this order (the things that use an object first):
Device:/> delete IPPolicy oc-publish-idauth
Device:/> delete IPPolicy oc-publish-crl
Device:/> delete IPPolicy oc-vpn-dns
Device:/> delete IPPolicy oc-vpn-to-lan
Device:/> delete IPPolicy oc-vpn-deny
Device:/> delete Interface OneConnectInterface oc-vpn
Device:/> delete OIDCProvider oc_idauth
Device:/> delete UserGroup oc_vpn_group
Device:/> delete Service ServiceTCPUDP oc_svc_idauth
Device:/> delete Service ServiceTCPUDP oc_svc_allowed
Device:/> delete Address IP4Address oc_lan_net
Device:/> delete Address IP4Address oc_proxy_ip
Device:/> delete Address IP4Address oc_dc_dns
Device:/> delete Address IP4Address oc_pool
Device:/> delete Address IP4Address oc_inner
Device:/> delete Address IP4Address oc_users_src
Device:/> delete LogReceiverSyslog oc_log
Device:/> delete Certificate oc_vpncert
Device:/> delete Certificate oc_ca
Device:/> activate
Device:/> commit
If show RemoteManagement RemoteMgmtSSH still lists ssh_idauth, delete it as at the end of step 7. Then put back the WebUI ports and DNS servers you wrote down in checks 3 and 4. Leave out what you did not change, and write an empty old value as "":
Device:/> set Settings RemoteMgmtSettings WWWSrv_HTTPSPort=443 WWWSrv_HTTPPort=80
Device:/> set DNS DNSServer1=<old 1> DNSServer2=<old 2> DNSServer3=<old 3>
Device:/> activate
Device:/> commit
Device:/> show -changes
show -changes must say There are no changes. After this the WebUI is on its old ports again. If script (it lists the uploaded scripts) still shows oidc.sgs, also run script -remove -name=oidc.sgs.
After either way, on the IdAuth host: systemctl disable --now idauth-proxy crl-web and rm /etc/cron.d/crl-renew. The inside DNS zone, the AD objects, IdAuth itself and the CA folder /opt/idauth-ca stay; remove them by hand if you want.
After either way, on each PC, in PowerShell as administrator, remove the CA. Replace ORG with the company name you used in step 1:
Get-ChildItem Cert:\LocalMachine\Root | Where-Object Subject -like "CN=ORG Internal CA*" | Remove-Item
Before you go live
- The sign-in page is a password prompt for your AD, on the internet. Anyone in USERS_SRC can try passwords there, and failed tries can lock accounts. Keep USERS_SRC as narrow as you can, check your AD lockout policy, and plan MFA in IdAuth (not tested here).
- The IdAuth host faces the internet. The firewall publishes PROXY_PORT (the sign-in page) and port 80 (the CRL) on it to USERS_SRC, and it holds ca.key. Keep it patched and use it for nothing else. crl-web is Python's small built-in web server; any web server that serves the file as application/pkix-crl will do.
- Every new VPN session needs IdAuth. Tunnels that are up should stay up; that was not tested. Plan a second IdAuth node, or a second way in.
- Removing a user from VPN_GROUP works at the next sign-in. It should not end a running tunnel (not tested). IdAuth also issues refresh tokens for 24 hours and remembers sign-ins (Allow SSO). If "disable the account and access is gone" must be true, shorten the refresh token lifetime and turn off Allow SSO, on the OpenID Provider edit page in IdAuth.
- What must keep running: the idauth container, and idauth-proxy, crl-web and cron on the IdAuth host. Keep a copy of /opt/idauth-ca in a safe, offline place: without ca.key you cannot renew the certificates or the CRL.
- Trust all (step 3a) must be off in production. With it on, IdAuth accepts any DC certificate, so a machine that pretends to be the DC gets the users' passwords. See "Turn off Trust all" below.
- The sign-in page opens in Swedish. Each user can switch it once: the settings button at the top right of the page (Inställningar), then Språk > English. The browser remembers it.
- The firewall log. oc_log sends the whole firewall log to SYSLOG_IP. Point it at your real log server, or delete LogReceiverSyslog oc_log.
- Renewals. The CRL: every week, by the cron file from step 1. vpn.crt and idauth.crt: after 397 days. Run step 1 again with FORCE_REISSUE=yes in front, upload oc_vpncert again as in 6a (the two vpn lines, then activate, commit; the SSH line is gone by then, so add it again for the upload and delete it after), and systemctl restart idauth-proxy. The CA: after 825 days. When the CA changes, replace oc_ca on the firewall and ca.crt on every PC on the same day.
- After any later change in the IdAuth portal, run step 4 again. If it prints CHANGE lines, restart IdAuth as in step 4.
- The proxy is the only front end that was tested. A production reverse proxy (nginx, HAProxy, Apache) that ends TLS and passes on the same four paths should work, but that was not tested; check with oidc before you rely on it.
- Rolling out to many PCs. The CA can go out as a trusted root with Intune, or with GPO: Computer Configuration > Policies > Windows Settings > Security Settings > Public Key Policies > Trusted Root Certification Authorities, import ca.crt. The OneConnect profile is set up in the user's own session (not as SYSTEM), with a click on Save. Do not e-mail profile links: a link that sets up a VPN looks like phishing. Edge offers to save the AD password on the sign-in page; turn that off by policy (PasswordManagerEnabled) if you do not want AD passwords in browsers. Rollout was not tested.
Turn off Trust all. IdAuth checks the DC against the Java trust store inside its container, not against the host. Give it the certificate of the CA that issued the DC’s LDAPS certificate. To see which CA that is, as root on the IdAuth host:
openssl s_client -connect DC_IP:636 </dev/null 2>/dev/null | grep issuer=
With AD CS it is the AD CS root CA, or the issuing CA below it if your AD CS has two levels. With Samba AD, copy /var/lib/samba/private/tls/ca.pem from the DC to the IdAuth host as dc-ca.cer. With AD CS, export that CA certificate on any domain-joined Windows PC, in PowerShell:
Get-ChildItem Cert:\LocalMachine\Root | Where-Object Subject -like "*<the DC's CA name>*" |
Select-Object -First 1 | Export-Certificate -FilePath .\dc-ca.cer
Use a part of the name that matches only one CA. A domain-joined PC lists the CA twice (it comes from two stores), so the line takes the first. An issuing CA below the root is in Cert:\LocalMachine\CA instead of Cert:\LocalMachine\Root. Copy dc-ca.cer to the IdAuth host. There, as root, in the folder that holds it:
docker exec -i idauth keytool -importcert -cacerts -storepass changeit -noprompt \
-alias dc-ldaps-ca < dc-ca.cer
docker restart idauth
It must say Certificate was added to keystore. changeit is the standard password of that trust store. Then in the IdAuth portal: Scenarios > Connections > LDAP > AD-LDAPS, untick Trust all, press Save, then Test connection: it must say Connection status: OK. Close the portal tab, run step 4 again, and run the step 5 test again. If Test connection says Failure, tick Trust all again and press Save, so that users can sign in. Most likely dc-ca.cer is not the CA that the issuer= line printed.
A new container starts with a fresh trust store. After every IdAuth upgrade, and after 01-idauth-container.sh with FORCE=yes, run the two lines above again. Until you do, Test connection says Failure and nobody can sign in.
Keep IdAuth and the DC on a server network, not on the network of users’ PCs. With Trust all off, IdAuth accepts a DC certificate that a CA in its trust store signed: the DC’s CA, or one of the public CAs that Java trusts. Host can stay DC_IP.
If it does not work
Find the first row that matches what you see. Do what it says. Then go back to the check you were on. The syslog from “Before you start” is the fastest way to see the reason.
| What you see | Step | Do this |
|---|---|---|
| sudo: command not found | before | Debian was installed with a root password. su -, apt install sudo, usermod -aG sudo <you>, then log in again |
| ssh FW_ADMIN@FW_MGMT_IP times out | before | SSH management does not allow this host. Add ssh_idauth as in "Before you start" |
| 02-make-ca.sh ends with a large NO CRL distribution point warning | 1 | CRL_URL was lost. Work as root (sudo -i), and run it again with FORCE_REISSUE=yes in front |
| 02-make-ca.sh: Permission denied | 1 | Not root. sudo -i first, and start the script with bash as shown |
| The idauth container restarts and never gets healthy | 2 | The licence is missing, or mounted as a file. ls /opt/pas-license/ must show license.p12 |
| 01-idauth-container.sh refuses to publish on every interface | 2 | BIND=IDAUTH_IP is missing. Work as root, with BIND in front |
| Test connection fails in the LDAP wizard | 3a | SSL is not on, LDAPS is not up on the DC (run the openssl s_client check again), or the Bind DN is not exactly SVC_DN or its password is wrong |
| 07-idauth-fixup.py: no relying party or no OpenID Provider allows | 4 | A wizard was skipped, or Allowed relying party was left empty in 3d |
| 05-verify-oidc.py: Temporary failure in name resolution | 5 | The host cannot resolve IDAUTH_NAME. Add the /etc/hosts line from "Before you start" |
| 05-verify-oidc.py: row 1 FAIL no authorization code | 5 | Wrong password, TEST_USER not under the search base (3b), or the account is locked |
| 05-verify-oidc.py: groups shows CN=... | 5 | IdAuth was not restarted after step 4. docker restart idauth |
| 05-verify-oidc.py: ERR_CERT_AUTHORITY_INVALID | 5 | IDAUTH_CA is not your ca.crt, or the proxy serves another certificate |
| fill-sheet.py: FileNotFoundError for sheet.txt | 5, 6 | The file is not in the scripts folder, or Windows saved it as sheet.txt.txt. ls shows it; mv sheet.txt.txt sheet.txt |
| 07-idauth-fixup.py: any other ERROR line | 4 | The line names the wizard or setting to fix. Fix it in the portal, close the tab, run step 4 again |
| fill-sheet.py: NOT WRITTEN | 5, 6 | It names the value that is missing, has a space, or is still an example. Fix sheet.txt |
| show Certificate does not list oc_vpncert or oc_ca after 6a | 6a | The scp went wrong (wrong password or path). Run the three lines again |
| script -execute stops: Command failed (oidc.sgs: Line N) | 6b | Read the error above it. reject -all, script -remove -name=oidc.sgs, fix sheet.txt, fill, upload, run again |
| oidc says Discovery retry | 6c | The firewall does not reach the proxy. Check 4 of step 6 (the firewall's DNS), then systemctl status idauth-proxy |
| oidc says Discovery completed but Loaded keys : 0 | 6c | The URLs inside IdAuth still say 8443. 07-idauth-fixup.py --proxy-url IDAUTH_URL, restart IdAuth, oidc -refresh |
| The syslog shows ssl_error against IDAUTH_IP | 6c | The firewall talks to 8443, not PROXY_PORT. The discovery URL on oc_idauth is wrong |
| userauth -privilege shows lines starting "CN= | 6c | A DN is in the group object. set UserGroup oc_vpn_group Members=VPN_GROUP, activate, commit |
| The script warns that the sign-in address or the CRL does not work from this PC | 7 | Run the public check of 6c on this PC. If the sign-in warning has trust in it, the CA is not installed: run Import-Certificate again, as administrator. For the CRL, see the next row |
| Connect does nothing, no browser opens, status stays Disconnected | 7 | The PC cannot check revocation. On the PC, (Invoke-WebRequest http://IDAUTH_NAME/ca.crl -UseBasicParsing).Headers['Content-Type'] must say application/pkix-crl. text/html means the firewall's own web page answered: check 3 (the WebUI on port 80). No answer: public DNS, USERS_SRC does not include the PC's public address, or the oc-publish-crl rule |
| The sign-in page shows empty fields with no labels | 7 | The proxy blocks /lang/. The --allow list must be /TENANT/,/authentication/,/web-app/,/lang/ |
| The browser said Authentication complete, but OneConnect still shows Disconnected | 7 | OneConnect was started from an administrator window. Close it completely, start it from the Start menu, and look again. userauth -list on the firewall shows the session |
| Authentication complete, then You are not authorized to log in, for a user who is in the group | 7 | Group mismatch. On the firewall: oidc -savetoken=START, connect again, oidc -savetoken=SHOW, and read groups in the token |
| The same, and the token's groups is right | 7 | The OneConnect server's Groups field must be VPN_GROUP exactly. Check it letter for letter: show Interface OneConnectInterface oc-vpn |
| Connected, but inside names do not resolve | 7 | oc-vpn-dns is not in the top five. show IPPolicy, then 6c |
| Connected, but nothing inside answers | 7 | The rule order in 6c, LAN_NET is not behind LAN_IF, or the inside hosts do not route VPN_POOL back through this firewall |
The scripts
All in scripts. Each one explains itself at the top. The numbers in the names are not the step numbers.
| Step | Script | Does |
|---|---|---|
| 1 | 02-make-ca.sh | Makes a CA, both server certificates and the CRL |
| 1 | crl-web.service | Serves ca.crl over plain HTTP |
| 2 | 01-idauth-container.sh | Runs IdAuth in Docker with the licence and a persistent configuration |
| 4 | 07-idauth-fixup.py | Sets the other settings. Safe to run again |
| 5 | 06-idauth-proxy.py, idauth-proxy.service | The reverse proxy, and its service |
| 5, 6 | fill-sheet.py, sheet-example-own-ca.txt | Fills your values into a file |
| 5 | 05-verify-oidc.py | Signs in as a user and checks the token |
| 6 | 03-netwall-own-ca.sgs | The firewall objects, one per line. Uploaded to the firewall |
| 7 | 04-windows-client.ps1 | Checks the sign-in page and the CRL, and creates the OneConnect profile. Runs on the PC |
03-netwall-own-ca.sgs runs on the firewall and 04-windows-client.ps1 on the PC; the others run on the IdAuth host. Ignore the files of the Let’s Encrypt setup: 03-netwall-letsencrypt.sgs, 02-make-proxy-cert.sh, idauth-proxy-http.service and sheet-example-letsencrypt.txt.
Reference setup
Tested on cOS Core 15.00.06.10 on two firewalls: one with an existing configuration, and a NetWall virtual firewall in a public cloud, behind NAT. Clavister IdAuth 7.0.2 in Docker on Debian 13, Samba AD, and OneConnect 3.15.4 on Windows 11. The Windows AD and DNS commands and the AD CS export were also run against Windows Server 2025 AD, in a run of the Windows own-CA guide. All seven steps were followed as written, from an empty IdAuth host. The test PC got the CA with Import-Certificate, and OneConnect checked the CRL. A member of VPN_GROUP connected and reached only LAN_NET on VPN_PORTS. A user outside the group was refused. Both ways back in “Remove it again” were tested. “Turn off Trust all” was tested on IdAuth 7.0.2 in Docker: Test connection said OK; without the CA, and again after a new container, it said Failure.
Not tested: an IdAuth that already serves other applications; keytool with an AD CS CA in “Turn off Trust all” (tested with a Samba CA); admins who log in through RADIUS; old IP Rules or rule folders; MFA; an HA firewall; mobile clients; more than one user at a time; rollout to many PCs; AD CS or a company CA in place of the CA of step 1; renewal of the certificates and the CA, and an expired CRL; a production reverse proxy; cOS Core versions other than 15.00.06.
Related articles
13 Aug, 2026 sase cloud oidc oneconnect core
28 Sep, 2026 core howto oneconnect oidc phenixid windows ad easyaccess certificate
28 Sep, 2026 core howto oneconnect oidc phenixid windows ad easyaccess linux letsencrypt
28 Sep, 2026 core howto oneconnect oidc phenixid windows ad easyaccess linux letsencrypt certificate
4 Jul, 2025 core oneconnect oidc
4 Nov, 2024 oidc core authentication
8 Feb, 2026 sase oneconnect core userauth oidc
28 Sep, 2026 core howto oneconnect oidc phenixid windows ad easyaccess letsencrypt