Creating a Simple Device Trust Gateway Using Device Certificates

In the evolving world of cybersecurity, identity-based access alone is no longer sufficient. The modern Zero Trust model mandates that access decisions consider not just the user but also the device. A user might be who they claim to be, but what if they’re logging in from a compromised machine or a jailbroken phone?

That’s where a device trust gateway comes in—a simple, scalable method to enforce access controls based on both user identity and device posture. Surprisingly, this doesn’t require complex architecture. In fact, with just a few lines of configuration in common web proxies like NGINX, you can create a robust checkpoint to validate device certificates before allowing application access.

In this post, we’ll explore how to build a simple yet effective device trust gateway using web proxy configurations, why it matters, and how it enhances your Zero Trust posture.

What Is a Device Trust Gateway?

device trust gateway is a proxy layer that sits in front of applications and checks whether the connecting device presents a valid, cryptographically signed certificate. This certificate—typically issued by a corporate Certificate Authority (CA)—acts as a machine identity, verifying that the device is registered, managed, and secure.

By validating the certificate before allowing a user session to proceed, organizations can enforce stronger controls such as:

  • Allowing access only from corporate-managed endpoints
  • Blocking jailbroken or unmanaged devices
  • Issuing short-lived access tokens only after successful posture checks

This approach complements MFA and SSO. Even if credentials are phished or stolen, an attacker can’t authenticate without access to a trusted device.

How It Works

  1. Device Enrollment: Devices are provisioned with client certificates from an internal CA.
  2. Proxy Enforcement: A reverse proxy (like NGINX or Apache) is configured to validate client certificates.
  3. Access Control: Only clients presenting valid certificates can reach upstream applications or IdPs (Identity Providers).
  4. Logging and Auditing: All device certificate checks are logged for forensics and compliance.

Why This Matters

In many organizations, devices are a weak link. Remote work, BYOD, and cloud-native services increase the risk of unmanaged or misconfigured endpoints.

By enabling device trust enforcement at the proxy level, you:

  • Avoid re-architecting your identity system
  • Add a powerful security control with minimal code changes
  • Stop attackers who steal credentials but don’t have trusted hardware

The best part? You likely already have the infrastructure to make it happen.

NGINX: Enforcing Client Certificate Validation

NGINX makes it straightforward to enable cleintAuth and client certificate validation.

server {
    listen 443 ssl;
    server_name secure.mycompany.com;

    ssl_certificate /etc/nginx/certs/server.crt;
    ssl_certificate_key /etc/nginx/certs/server.key;
    ssl_client_certificate /etc/nginx/certs/ca.crt; # Your CA Chain
    ssl_verify_client on;# <‑ key line

    location / {
        proxy_pass http://internal-app;
        proxy_set_header X-Client-Cert $ssl_client_cert;
        proxy_set_header X-Client-DN  $ssl_client_s_dn;
    }
}

In this snippet:

  • ssl_client_certificate points to the CA that signed your device certificates
  • ssl_verify_client on enforces certificate presentation
  • The subject DN is passed upstream for audit or additional policy checks

If a device doesn’t present a valid certificate, NGINX terminates the connection.

Note: The client cert can be passed to through the proxy to other backend services using the nginx variable $ssl_client_cert which contains the entire URL encoded client certificate in PEM format.

Optional: Enforce Device Policies

If you want to go beyond “certificate is valid” and enforce per‑device rules, leverage OpenSSL extensions or X.509 Subject Alternative Names (SAN). For example:

# Add a custom extension in the CSR:
openssl req -new -key device-01.key.pem \
    -subj "/CN=device-01.acme.com/O=Acme Devices/C=US" \
    -addext "subjectAltName = @alt_names" \
    -config <(cat /etc/ssl/openssl.cnf <(printf "[alt_names]\nrole=admin\n"))

Then in nginx you can inspect $ssl_client_s_dn or $ssl_client_cert and use map directives to block or allow based on the role.

Apache HTTPD: A Similar ClientAuth Approach

Apache’s mod_ssl module can perform the same function.

<VirtualHost *:443>
    ServerName secure.mycompany.com

    SSLEngine on
    SSLCertificateFile /etc/httpd/certs/server.crt
    SSLCertificateKeyFile /etc/httpd/certs/server.key
    SSLCACertificateFile /etc/httpd/certs/ca.crt
    SSLVerifyClient require

    <Location />
        ProxyPass http://internal-app/
        ProxyPassReverse http://internal-app/
    </Location>
</VirtualHost>

Apache enforces client cert verification with SSLVerifyClient require, ensuring only trusted devices make it through.

Monitoring & Logging

Nginx logs each handshake, including whether client cert verification succeeded. Add a custom log format:

log_format devicelog '$remote_addr - $remote_user [$time_local] '
                     '"$request" $status $body_bytes_sent '
                     'client_cert="$ssl_client_verify" '
                     'cn="$ssl_client_s_dn"';
access_log /var/log/nginx/device_access.log devicelog;

Now you can audit which devices accessed the gateway, detect expired certs, or spot anomalies.

Testing the Gateway

Valid Device – On a client machine, install device-01.cert.pem and device-01.key.pem. Or use curl:

curl -k --cert device-01.cert.pem \
     --key  device-01.key.pem \
     https://proxy.acme.com/

You should get the backend response.

  • Invalid Device – Remove or rename the cert/key and try again; you’ll receive a 403.
  • Expired Certificate – Tamper with device-01.cert.pem’s validity period or use openssl x509 -in device-01.cert.pem -noout -dates to verify expiration. The gateway will reject it automatically.

Device Trust Gateway Flow

Device Trust Gateway Authentication work flow

Steps:

  1. Device connects to proxy and presents client certificate
  2. Proxy checks cert against trusted CA
  3. If valid, forwards request to application
  4. If invalid, terminates connection

Implementation Tips

  • Use short-lived device certificates (e.g., 24 hours)
  • Automate provisioning with MDM scripts and/or SCEP
  • Use headers like X-Client-Cert to enrich identity at the application layer
  • Monitor failed certificate handshakes as potential threats

Conclusion

  • Fast Implementation – Adding just two lines (ssl_verify_client on + ssl_client_certificate) turns any TLS‑enabled proxy into a device trust gateway.
  • Zero‑Trust Foundation – Every device must prove its identity before accessing sensitive resources.
  • Scalable – The same CAs can issue thousands of certificates; you can automate provisioning via scripts or PKI tools like step-ca.

Final Thoughts

You don’t need to overhaul your infrastructure to implement device trust. Adding a few lines of proxy configuration can provide a powerful gateway that ensures only secure, trusted devices can access your applications.

In a Zero Trust world, identity is not enough. Trust must be earned—and verified—by the devices themselves.

Kubernetes Harvester to Gather Credentials with Limited Access

Project URL: https://github.com/sleventyeleven/Kubernetes-Harvester

Kubernetes Harvester Example Run

What is Kubernetes Harvester?

Harvester is a new python based project that attempts to leverage access in order to gather potentially sensitive information. Its designed to either leverage the access of users credentials or the default access granted to a pod via automountServiceAccountToken, which I wrote about recently. The harvester.py script currently primarily targets pod container environment variables, container manifest environment variables, and config map entries utilized as environment variables, to look for potential credentials.

Why Create A Credential Harvester

The default admission controls in many of the Kubernetes implementation apply a read/view policy to newly created users. However custom policies, admissions, and operators have become more common place. What’s more troublesome is the read permissions given to the automountServiceAccountToken by default. Without adjusting or disabling service tokens, compromised containers could effectively read all pod specs in all namespaces. With access to all pod specs, an attacker could potentially gather credentials or other sensitive information. Harvester is a tool that attempts to help automate the review process.

How Kubernetes Harvester Works

The harvester.py script utilizes the automountServiceAccountToken mounted within a given container or the standard user credentials within the Kube config file (~/.kube/config). Then the Kube API server is queried to look for sensitive information within the pod spec of each pod in the following steps.

  1. Use access to request pod specs for all namespaces within the cluster.
  2. Parse all pod specs to map and dedupe container container information
  3. Review each containers environment variables for sensitive values
  4. Review each config map entry, mapped to container environment variables for sensitive values
  5. Attempt to pull each container image and review the manifest environment variables for sensitive values
  6. Attempt to request authentication tokens from the internal metadata API for each of the major cloud provider

Other Resources:

  • Introduction to Kubernetes – A Free introduction course diving into Kubernetes as a tool for containerized infrastructure. Its a a great place to begin if your just getting started with Kubernetes.
  • The Linux Foundations Official Course – This is the most robust general knowledge based course I’ve seen. If you want to learn Kubernetes and how to do almost anything with it, get the CKA + CKAD combo package.

Sometimes You Just Have to Proxy Your Socks Off

Problem

Sometimes during assessments sensitive systems are significantly segmented from other networks. Therefore its very important for penetration testers to know how to proxy your socks off in order to move across network.

Solution

To gain access to other networks, whether it’s the internet or a protected subnet. We can use putty on windows and the native ssh client on Linux to preform port forwarding and create Socks proxies to bypass access controls.

Proxy Your Socks Off - Web server Post Exploitation with SSH Tunnels and Socks Proxy

Proxy Caveats

SOCKS proxies only work for TCP traffic and with applications that support using a transparent proxy. Applications that use their own proxy settings, require forward secrecy, or check session integrity likely won’t function correctly.

All ports from 1-1024 require administrative rights to allocate on both windows and Linux systems.

Port 0 is used to represent a randomly generated port number, in both windows and linux systems.

How to Proxy Your Socks Off

Proxy Traffic in Windows

In Windows simply open putty and enter the IP address you want to connect  in as the Hostname/IP address.

Proxy your socks off - configure Putty SSH connections

Next we have to tell putty that we want it to open a port on the localhost to be used to forward all traffic to our remote host. To do that, we go to the connections -> SSH -> Tunnels section, add a source port, choose the Dynamic option, and click the add button.

Proxy your socks off - configure Putty SSH for dynamic port forwarding options

At this point you can click the open button and authenticate as if it were a normal SSH connection. Just be sure to leave the terminal open once authenticated, to ensure traffic is being passed from the local port to the remote host.

To tell windows to use the socks proxy, open internet options from the control panel or the start menu search. Then go to the connections tab and open LAN Settings.

Proxy your socks off - configure Control Panel Internet Properties for Socks Proxy

Once LAN settings opens, select the “use a proxy server for your LAN” check box and click the advanced.

Proxy your socks off - configure Windows Lan Settings for Socks Proxy

In the Socks box add localhost or 127.0.0.1 and the port you set as dynamic in putty. Then click OK three times to save all the settings.

Proxy your socks off - configure Windows Advanced Proxy Settings for Socks Proxy

Proxy Traffic in Linux

If you need to proxy your Kali system, the process is fairly similar. Start by using the ssh client to dynamically forward traffic from a local port. This can be done with a command similar to the following, where 9050 is our dynamic port.

ssh -NfD 9050 root@159.246.29.206

Next we need to tell proxy chains where to send traffic from our programs. This can be set globally be using a command like the following.

echo "socks4\t127.0.0.1\t9050" >> /etc/proxychains.conf

To run an application through the socks proxy, simply prepend it with the proxychains command, like the following.

proxychains iceweasel

There is not built in means to setup a system wide socks proxy. However the BadVPN package has a package tun2socks that can tunnel all traffic over a local socks proxy.

Proxy Your Socks Off with Metasploit

Sometimes, while doing an assessment you may even want to run some tools such as nmap or even SQL Management studio (ssms.exe) over an established shell. Metasploit has a post module (auxiliary/server/socks4a) that can be used to create a socks4 proxy on an existing session.

However, to start off we need to tell metasploit how to route traffic to each of our shell’s networks before running the socks proxy. This can either be done manually with the route command or if your session is on a windows host with the autoroute module (post/windows/manage/autoroute).

To add a route manually you can use the built in route command with options similar to the following.

route add 10.0.0.0 255.255.255.0 1

To add routes with autoroute, either use the post module or run autoroute from a meterpreter shell. For the autoroute module (post/windows/manage/autoroute) just set the session ID and run. For autoroute from meterpreter use a command similar to the following.

run autoroute -s 10.0.0.0

Once routes are established within metasploit to your target networks, you can run the socks proxy module (auxiliary/server/socks4a) and note the SRVPORT.

Using Proxychains to Proxy Traffic through Metasploit Meterpreter

Next we need to tell proxychains what port to send traffic to within the global configuration file (/etc/proxychains.conf), just like in the Linux example above. There should be a line like “socks4 127.0.0.1 1080” at the bottom of the file, change the port 1080 to whatever your SRVPORT was in metasploit.

Once the configuration file is updated, proxychains can be used to issue commands through metasploit shell(s). Like with the following nmap example.

proxychains nmap -v -sS 10.0.0.0/24

If we want to make this socks proxy available to a windows host for programs like SQL Server Management Studio, perform a local port forward  to the socks port on the Linux system. To do this we can use putty and follow steps similar to those presented above.

Start by creating a local port forward of a local port on our windows system, to the local socks port on the Linux system with putty. Start by allocating a source port for connection on the local system and forward to a destination of 127.0.0.1:1080; where 1080 is your metasploit SRVPORT.

Proxy your socks off - configure Putty SSH to allocate local port to connect to remote Socks Proxy

We can then just configure a system wide proxy by adding our forwarded port as the socks port, instead of using a local socks proxy.

Proxy your socks off - configure Windows Advanced Proxy Settings for forwarded Socks Proxy

Once those settings are changes, we should be able to use the majority of our tools within windows without issue.

Using SSH to Provide Remote System Internet Access via local Socks Proxy

An SSH tunnel can be used to forward traffic from your local system to a port on a remote system. This can be done in Linux by switching the -L option with -R. Or in putty by choosing the Remote option under tunnels instead of Local. For example if you wanted to share your local socks proxy with a remote system to provide internet access, putty can be used with a remote forward like the following.

Proxy your socks off - configure Putty SSH to allow remote host internet access via a remote port forward to a local socks proxy

Using Compromised Linux Webserver to Access Internal Network and Database

It’s also worth noting that SSH port forwarding can be performed on the network socket level and does not require an interactive session be established; only valid authentication is required. For instance, say you wanted to log into a restricted database of a webserver. But you only have access to the webserver account. The webserver user is not allowed to log into the server interactively by default, but that doesn’t mean it can’t authenticate. In many cases SSH can be used as described in my post on SSH for post exploitation to get around limited user shells.

Using Linux Native Tools to Proxy Your Socks Off

Tools natively built-in to windows and linux can also be used to preform port forwarding. Just note that this methodology simply makes a port to port translation and does not manipulate the traffic in any way. Netcat (nc) is found in almost every single Linux distribution and can be used to easily preform port forwarding with commands similar to the following.

First we have to make a named pipe so that any response from the server aren’t dumped to standard out.

mkfifo backpipe

Then we can use a command similar to the following to send traffic from 8080 on the localhost to a remote host on a different port utilizing the named pipe. This could help get around a firewall or help send traffic to another system to be caught by another port translation or process.

nc -l 8080 0<backpipe | nc example.com 80 1>backpipe

Similarly the netsh (commandline windows firewall editor) command in windows can be used to create a local port forward as well. In this cause we can follow the same example and create a port translation from localhost 8080 to example.com on port 80.

netsh interface portproxy add v4tov4 listenport=8080 listenaddress=127.0.0.1 connectport=80 connectaddress=example.com

Windows 7 and above will likely require administrative privileges to make changes to the windows firewall. But you can likely still utilize the windows version of nc or netcat to redirect traffic all the same.