A tunnel is not an access policy

A support engineer needs remote SSH access to one server, not unrestricted access to the company network. OpenVPN provides the private-network connection and the firewall defines its permitted scope. This example combines certificates, a PPP account, return routing and forward ACLs, then tests both permitted SSH and a forbidden destination; establishing the tunnel is not the final check.

Version, PKI and management access

Named-server syntax targets RouterOS 7.17 onward. The client example uses OpenVPN Community 2.6. Test and record the selected router/client patches before deployment.

Measure router CPU, tunnel count and throughput under load. Avoid overlap with LAN or other VPN pools. This example uses TCP/1194.

Create the CA, server and client certificates on this MikroTik using the commands below. Match the real VPN DNS name in SAN and CN. Correct clocks, console access and off-router encrypted backups are required.

RouterOS versions and transport differences

Before 7.17, servers used different singleton syntax. UDP and cipher support depend on release. TCP here targets compatibility, but TCP-over-TCP suffers under loss. Validate UDP against both peers and firewall policy before selecting it.

Before connecting from the Internet, point the real VPN DNS name to a reachable public address and verify that WAN contains the intended external interface. If MikroTik is behind another router, forward TCP/1194 on that upstream device to MikroTik. With ISP CGNAT and no inbound mapping, this listener is not directly reachable from the Internet; obtain an inbound-reachable address or another access design. Do not add a self-referencing default gateway.

VPN forward and return paths

After certificate and PPP checks, pool traffic passes through forward ACLs. Destination routing must return the pool through this router. Include the pool in any source-restricted server SSH policy. NAT that hides missing routes is not the default design.

Example: split-tunnel SSH to one server

The pool is 10.250.0.0/24 and the permitted destination is 10.20.30.10. The client receives only that host route. Allocate individual accounts/certificates and replace addresses with your IP plan.

The LAN server's replies must find the VPN network too. If this MikroTik is its gateway, active PPP routes normally provide that path. Otherwise, add a route for 10.250.0.0/24 on the server's actual gateway, using this router's LAN address as next hop. The WAN masquerade example below serves Internet egress and does not replace that LAN return route.

Individual certificates and revocation

Leave compression disabled and assign individual credentials. Require-client-certificate alone does not bind a certificate to a specific username. Negatively test identity mapping. Revoke PPP access, certificates and sessions during offboarding. MFA requires a compatible identity/RADIUS design beyond this example.

Create certificates and configure server/client

1. Create the CA on MikroTik

Run the certificate commands in WinBox → New Terminal on the target MikroTik; this stage does not need a separate Linux server. Check the router clock and unused certificate names first. After each sign command, wait for signing to finish before proceeding so a failure is not hidden by later steps.

ROUTEROS
/system clock print
/certificate add name=ovpn-ca-template common-name=OVPN-CA key-size=2048 days-valid=3650 key-usage=key-cert-sign,crl-sign
/certificate sign ovpn-ca-template name=ovpn-ca
/certificate set [find where name="ovpn-ca"] trusted=yes

2. Create and sign the server certificate

Replace vpn.example.com in common-name and subject-alt-name with your real VPN DNS name. Use the same name in remote and verify-x509-name in the client configuration below.

ROUTEROS
/certificate add name=ovpn-server-template common-name=vpn.example.com subject-alt-name=DNS:vpn.example.com key-size=2048 days-valid=365 key-usage=digital-signature,key-encipherment,tls-server
/certificate sign ovpn-server-template ca=ovpn-ca name=ovpn-server
/certificate set [find where name="ovpn-server"] trusted=yes

3. Create and sign the client certificate

opsvpn is the example PPP user below. Create a separate certificate and key for each person, using a unique name and common-name. Matching the CN to the username alone does not enforce that identity mapping.

ROUTEROS
/certificate add name=ovpn-client-template common-name=opsvpn key-size=2048 days-valid=365 key-usage=digital-signature,tls-client
/certificate sign ovpn-client-template ca=ovpn-ca name=ovpn-client
/certificate print detail

Check that ovpn-ca is an authority and trusted, ovpn-server has a private key and tls-server usage, and ovpn-client has a private key and tls-client usage. Check validity dates and the server DNS SAN. Since these certificates were created on this router, do not import ca.crt or server.p12 into it.

4. Export the files needed by the client

Replace the export password with a strong, unique value. The CA export intentionally has no export-passphrase, so it exports only the public certificate. The client export includes an encrypted private key. Export requires the sensitive policy.

ROUTEROS
/certificate export-certificate ovpn-ca type=pem file-name=ca
/certificate export-certificate ovpn-client type=pem file-name=client export-passphrase="REPLACE_WITH_STRONG_CLIENT_KEY_PASSWORD"
/file print

Download ca.crt, client.crt and client.key from WinBox → Files through your secure management connection. Put them beside client.ovpn on that user’s computer. Enter the export password when OpenVPN asks for the private-key password. After safe delivery, remove only the exported client.key file from Files, not the certificate in System → Certificates. Do not export or share the CA/server private keys. This method keeps the CA key on the router; protect its management access and encrypted backups.

5. Configure the OpenVPN server

Use certificate=ovpn-server: this is the server certificate signed above. Replace the PPP password before running the commands.

ROUTEROS
/ip pool add name=ent-ovpn-pool ranges=10.250.0.10-10.250.0.100
/ppp profile add name=ent-ovpn local-address=10.250.0.1 remote-address=ent-ovpn-pool
/ppp secret add name=opsvpn service=ovpn password="REPLACE_WITH_UNIQUE_USER_SECRET" profile=ent-ovpn
/interface ovpn-server server add name=ent-ovpn-server disabled=yes protocol=tcp port=1194 mode=ip certificate=ovpn-server require-client-certificate=yes auth=sha256 cipher=aes256-cbc tls-version=only-1.2 default-profile=ent-ovpn
/ip firewall filter add chain=input in-interface-list=WAN protocol=tcp dst-port=1194 action=accept comment="ENT-OVPN listener"
/ip firewall filter add chain=forward src-address=10.250.0.0/24 dst-address=10.20.30.10 protocol=tcp dst-port=22 action=accept comment="ENT-OVPN SSH grant"
/ip firewall filter add chain=forward src-address=10.250.0.0/24 action=drop comment="ENT-OVPN deny other"

The listener is deliberately created disabled so the firewall can be prepared first. In input, place ENT-OVPN listener before the drop blocking it while preserving management protection. In forward, put ENT-OVPN SSH grant immediately before ENT-OVPN deny other, with both above general accepts or FastTrack. Established/related handling must allow replies. Check the order with the following commands and enable the listener only after placement is correct.

ROUTEROS
/ip firewall filter print detail
/interface ovpn-server server enable [find where name="ent-ovpn-server"]

6. Create client.ovpn

Save the following as client.ovpn beside the three exported files. Replace vpn.example.com in both remote and verify-x509-name.

OPENVPN
client
dev tun
proto tcp-client
remote vpn.example.com 1194
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
auth-user-pass
remote-cert-tls server
verify-x509-name vpn.example.com name
tls-version-min 1.2
auth SHA256
cipher AES-256-CBC
data-ciphers AES-256-CBC
route 10.20.30.10 255.255.255.255
verb 3

This CBC configuration targets OpenVPN Community 2.6 (OpenVPN GUI on Windows), not every app called OpenVPN. Some OpenVPN Connect / OpenVPN 3 clients disable legacy CBC ciphers. On Linux, run sudo openvpn --config client.ovpn; on Windows, import the profile into OpenVPN GUI. Enter PPP credentials and the encrypted key password. After Initialization Sequence Completed, test permitted SSH and denied destinations. For newer client apps, choose and validate a matching GCM configuration on both peers instead of importing this profile unchanged.

MikroTik: create, sign and export certificates

Pool, sessions and certificate expiry

Monitor active PPP sessions, pool use, authentication failures and certificate expiry. Distinguish one user’s disconnect from listener failure. Allow enough expiry-warning time for issuance and deployment.

Certificate, session and access-policy verification

ROUTEROS
/interface ovpn-server server print detail
/ppp active print detail
/certificate print detail
/ip firewall filter print stats where comment~"ENT-OVPN"
/log print where topics~"ovpn|ppp"

Expected: the named listener is enabled, the individual user has a pool address, certificates are valid and the SSH grant counter increases for the authorized destination. On the client, test the granted SSH port and a deliberately unauthorized port/server with a bounded TCP test. The latter must fail while the allowed one works. AUTH_FAILED is different from TLS verification failure; a connected PPP session is not proof of forwarding permission. Restrict logs because usernames and network details are sensitive.

From TLS errors to SSH timeouts

Let the error identify the layer. Investigate TLS Error through the clock, CA, CN/SAN and key usage; AUTH_FAILED points to the PPP service, password or account policy. A connected tunnel with SSH timeout requires checking return routes, forward counters and the server firewall. Keep cipher and SHA256 settings aligned; adding GCM without checking versions and authentication is not a general fix.

Send Internet traffic through the VPN (optional full tunnel)

The main example routes only 10.20.30.10 through the VPN. For IPv4 Internet access through MikroTik, enable redirect-gateway=def1 on this named server as shown below. RouterOS sends the redirect to connecting clients; reconnect afterward. The client must accept pushed options (the client directive already includes pull). You may also set redirect-gateway def1 locally in client.ovpn, but both are not required. This does not configure DNS or tunnel IPv6.

ROUTEROS
/interface ovpn-server server set [find where name="ent-ovpn-server"] redirect-gateway=def1

Optional client-side equivalent in client.ovpn:

OPENVPN
redirect-gateway def1

The example firewall currently drops every other VPN destination. Add a WAN-only forward grant before ENT-OVPN deny other, then source NAT the VPN pool to WAN. WAN must contain only the intended Internet-facing interface(s); the router needs a working default route and upstream connection. Existing established/related rules must permit replies. If an existing source-NAT rule already covers this pool and WAN, reuse it rather than adding another.

ROUTEROS
/ip firewall filter add chain=forward src-address=10.250.0.0/24 out-interface-list=WAN action=accept place-before=[find where comment="ENT-OVPN deny other"] comment="ENT-OVPN Internet grant"
/ip firewall nat add chain=srcnat src-address=10.250.0.0/24 out-interface-list=WAN action=masquerade comment="ENT-OVPN Internet NAT"

Set a DNS resolver reachable through WAN in the client VPN adapter/profile. Redirecting routes does not automatically update Linux system DNS; verify resolver selection on the actual OS. Check 0.0.0.0/1 and 128.0.0.0/1 routes, compare the public IPv4 with MikroTik egress, then test DNS and filter/NAT counters. IPv6 can still use the client’s local Internet connection; this IPv4 example does not prevent IPv6 bypass. Private-network access remains subject to existing rules.

Mangle for TCP MSS problems, when needed

Ordinary single-WAN routing does not require routing marks. Mangle is useful here for TCP MSS adjustment when the tunnel connects but large transfers or websites stall because of PMTU problems. First check whether the PPP profile already handles MSS with change-tcp-mss; avoid duplicate adjustments. If manual clamping is needed, use these VPN-pool-scoped rules in both directions. Do not block ICMP fragmentation-needed messages. MSS rules do not create routes, replace NAT or fix every MTU problem.

ROUTEROS
/ppp profile print detail where name="ent-ovpn"
/ip firewall mangle add chain=forward src-address=10.250.0.0/24 protocol=tcp tcp-flags=syn action=change-mss new-mss=clamp-to-pmtu passthrough=yes comment="ENT-OVPN MSS from clients"
/ip firewall mangle add chain=forward dst-address=10.250.0.0/24 protocol=tcp tcp-flags=syn action=change-mss new-mss=clamp-to-pmtu passthrough=yes comment="ENT-OVPN MSS to clients"

With multiple WANs or policy routing, design the egress table and FastTrack exclusions before using connection/routing marks. These MSS rules do not select a WAN. SYN/SYN-ACK MSS handling must run before a matching earlier Mangle accept rule; do not assume all VPN packets hit Mangle after a flow is FastTracked. Test fresh TCP connections. For rollback use the scoped commands in the recovery section and remove any client-side redirect too.

ROUTEROS
/interface ovpn-server server print detail where name="ent-ovpn-server"
/ip route print detail where dst-address="0.0.0.0/0"
/interface list member print where list="WAN"
/ip firewall filter print stats where comment~"ENT-OVPN"
/ip firewall nat print stats where comment~"ENT-OVPN"
/ip firewall mangle print stats where comment~"ENT-OVPN MSS"

MikroTik OpenVPN server: redirect-gateway

MikroTik Mangle: change-mss and routing marks

OpenVPN: routing all client traffic through the VPN

OpenVPN 2.6: cipher compatibility and client options

Revocation and configuration rollback

Keep recovery scoped to this change. Protect the secret-free export, encrypted backup and PKI material, and test CRL rejection with a revoked certificate on the target patch. To roll back this example, disable its named server, ENT-OVPN rules and client route. Correcting one rule does not require restoring the entire router.

Test forbidden access too

Test forbidden destinations and ports alongside permitted SSH. Router counters must agree with the results. This compatibility-oriented cipher choice requires organizational cryptographic-policy review.

Scope rollback to this named server

ROUTEROS
/interface ovpn-server server disable [find where name="ent-ovpn-server"]
/ppp secret disable [find where name="opsvpn"]
/ppp active remove [find where name="opsvpn"]
/ip firewall filter disable [find where comment~"ENT-OVPN"]
/ip firewall nat disable [find where comment="ENT-OVPN Internet NAT"]
/ip firewall mangle disable [find where comment="ENT-OVPN MSS from clients"]
/ip firewall mangle disable [find where comment="ENT-OVPN MSS to clients"]
/interface ovpn-server server set [find where name="ent-ovpn-server"] redirect-gateway=disabled

These are disruptive changes: they terminate the example user’s tunnel and deny its next login. Review the exact matches before execution. Disabling a PPP secret alone does not necessarily terminate an existing session. Remove only associated client routes/settings and revoke certificates through the PKI workflow when offboarding; this rollback does not replace a tested CRL policy. This rollback also disables only the example NAT/MSS rules and resets the named server redirect. Remove redirect-gateway def1 from any edited client profile. Do not disable unrelated NAT or Mangle rules.

Best Practices

  • Version-control configuration and review changes.
  • Use least privilege and explicit allow-lists.
  • Automate repeatable checks and monitor the expected state.
  • Test upgrades and restores before production rollout.

Conclusion

A reliable implementation of Set Up OpenVPN on RouterOS v7 with Restricted Access is more than a successful first run. Keep the configuration documented, observable, recoverable, and aligned with the team's change-management process.

Frequently Asked Questions

Why can the tunnel connect while SSH fails?

Return routing and forward ACLs are independent of authentication.

Do all v7 patches use identical configuration?

No. Named-server configuration changed in 7.17. Pin and validate the target patch.

Official Sources

Share

Meet AJInfrastructure & DevOps
Loading…