-
Notifications
You must be signed in to change notification settings - Fork 0
Service Setup
Socket Firewall can run as a persistent service, making it ideal for Docker deployments, CI/CD pipeline integration, and environments where you need manual proxy configuration. In service mode, the proxy server runs continuously.
Run Socket Firewall as a persistent service:
# Required environment variables for service mode
# Required scopes: packages, entitlements:list
export SOCKET_API_KEY=sktsec_your_api_key_here_api
export SFW_HOSTNAME=your.proxy.hostname
export SFW_CA_CERT_PATH=/path/to/ca.crt
export SFW_CA_KEY_PATH=/path/to/ca.key
# See the full list of configuration options in the documentation below
sfw --service
Note: These environment variables are only required for service mode. In wrapper mode, the CLI handles configuration automatically, requiring only the SOCKET_API_KEY
.
Here is an example Dockerfile
for building and running Socket Firewall in your environment:
FROM debian:bullseye-slim
# netcat included for healthcheck
RUN apt-get update && apt-get install -y netcat-openbsd \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN mkdir -p /app/certs /run/secrets
RUN curl -L "https://github.com/SocketDev/firewall-release/releases/latest/download/sfw-linux-x86_64" -o ./sfw
RUN chmod +x ./sfw
RUN mv ./sfw /usr/local/bin/sfw
COPY ./ca.crt /app/certs/ca.crt
COPY ./ca.key /app/certs/ca.key
ENV SFW_HTTP_PORT=80
ENV SFW_HTTPS_PORT=443
EXPOSE 80
EXPOSE 443
ENTRYPOINT ["/usr/local/bin/sfw", "--service"]
It can be built like so:
docker build -t socket-firewall:latest -f Dockerfile .
Alternately, this Docker Compose file can be used as a starting point:
name: socket-firewall
services:
firewall:
build:
context: .
dockerfile: ./Dockerfile
ports:
- "80:80"
- "443:443"
environment:
- SFW_HOSTNAME=your.proxy.hostname
- SFW_CA_CERT_PATH=/app/certs/ca.crt
- SFW_CA_KEY_PATH=/app/certs/ca.key
volumes:
# You need to generate these and provide in PEM format
- path/to/socketFirewallCa.crt:/app/certs/ca.crt:ro
- path/to/socketFirewallCa.key:/app/certs/ca.key:ro
secrets:
- dot-env-secrets
healthcheck:
test: ["CMD", "nc", "-w", "1", "-z", "localhost", "443"]
interval: 5s
timeout: 2s
retries: 5
secrets:
dot-env-secrets:
# Should include your SOCKET_API_KEY as an entry in dotenv format
# Required scopes: packages, entitlements:list
file: ./.env.secrets
The proxy loads configuration from multiple sources in order:
-
.sfw.config
(current directory) -
.sfw.config
(parent directories) -
.sfw.config
(home directory) -
/run/secrets/dot-env-secrets
(Docker secrets)
-
SOCKET_API_KEY
(required, string): Socket API token. -
SFW_HTTP_PORT
(optional, number): Port on which to listen for HTTP CONNECT requests. Defaults to 80. -
SFW_HTTPS_PORT
(optional, number): Port on which to listen for HTTP CONNECT requests. Defaults to 443. -
SFW_HOSTNAME
(required, string): The hostname which will be used to address the proxy server. -
SFW_CA_CERT_PATH
(required, string): Path to a PEM-encoded CA certificate file. -
SFW_CA_KEY_PATH
(required, string): Path to a PEM-encoded CA key file. -
SFW_ALLOW_BAD_DESTINATION_CERT
(optional,true
): Will ignore SSL errors when connecting to destination hosts. Must be set to the stringtrue
for the option to take effect. -
SFW_CUSTOM_REGISTRIES
(optional, string): A new-line delimited set of custom registry entries. See below for details.
As noted above, Socket Firewall can filter traffic for custom registries. Each entry must take the form kind:fqdn
or kind:fqdn/url-prefix
.
Valid custom registry kinds are as follows:
gem
golang
maven
npm
pypi
cargo
nuget
-
block
- all traffic to the specified host will be blocked -
wrap
- all traffic to the specified host will be blindly forwarded without inspecting requests
The FQDN value should match the exact hostname that your package manager is configured to use.
An optional URL prefix is allowed. Some private registry services support multiple types of package manager, determined by the first part of the path. For example, you might have an .npmrc
file that looks something like this:
; The trailing slash is required
registry=https://packages.example.com/npm-mirror/
; Auth token scoped to the exact host + path prefix
always-auth=true
//packages.example.com/npm-mirror/:_authToken=${NPM_TOKEN}
; You've installed the Socket Firewall CA locally, so you can trust the proxied TLS connection
strict-ssl=true
If this were your npm configuration, the corresponding custom registry config would look like this:
export SFW_CUSTOM_REGISTRIES='npm:packages.example.com/npm-mirror'
When configured in this way, Socket Firewall will intercept traffic to packages.example.com
in the same way it does for standard public registries.
When Socket Firewall blocks a package manager's request, it will:
- return a
403
response - include a response body with a human-readable explanation for what happened
- add a
X-Block-Reason
header containing a comma-delimited list of reasons for the block
After standing up the service, you should confirm that the service is healthy and ready to filter network traffic from package managers.
You can accomplish this in the terminal:
curl -v \
--proxy https://your-firewall-host:443 \
--proxy-cacert path/to/socketFirewallCa.crt \
--cacert path/to/socketFirewallCa.crt \
https://registry.npmjs.org/lodash/-/lodash-1.0.0.tgz
You should make sure to pick a package URL that you know will be filtered based on your Socket org preferences.
If the CA is configured correctly, if the service is running, and if Socket determines the package should be blocked, you'll see output similar to the following:
* Host your-firewall-host:443 was resolved.
* IPv6: (none)
* IPv4: x.x.x.x
* Trying x.x.x.x:443...
* Connected to your-firewall-host (x.x.x.x) port 443
* ALPN: curl offers http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* CAfile: /path/to/socketFirewallCa.crt
* CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384 / [blank] / UNDEF
* ALPN: server accepted http/1.1
* Proxy certificate:
* subject: CN=your-firewall-host
* start date: Aug 24 02:02:23 2025 GMT
* expire date: Aug 24 02:02:23 2026 GMT
* subjectAltName: host "your-firewall-host" matched cert's "your-firewall-host"
* issuer: CN=Socket Security CA; O=Socket Security
* SSL certificate verify ok.
* CONNECT tunnel: HTTP/1.1 negotiated
* allocate connect buffer
* Establish HTTP proxy tunnel to registry.npmjs.org:443
> CONNECT registry.npmjs.org:443 HTTP/1.1
> Host: registry.npmjs.org:443
> User-Agent: curl/8.7.1
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection Established
<
* CONNECT phase completed
* CONNECT tunnel established, response 200
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
* subject: CN=registry.npmjs.org
* start date: Aug 24 02:08:28 2025 GMT
* expire date: Aug 24 02:08:28 2026 GMT
* subjectAltName: host "registry.npmjs.org" matched cert's "registry.npmjs.org"
* issuer: CN=Socket Security CA; O=Socket Security
* SSL certificate verify ok.
* using HTTP/1.x
> GET /lodash/-/lodash-1.0.0.tgz HTTP/1.1
> Host: registry.npmjs.org
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 403 Forbidden
< Content-Type: text/plain
< Connection: close
< X-Block-Reason: npm package 'lodash@1.0.0' was blocked
<
* Closing connection
Package blocked for violating organization security policy