Skip to content

Release repository for the Socket Registry Firewall artifacts

Notifications You must be signed in to change notification settings

SocketDev/socket-registry-firewall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 

Socket Registry Firewall

Enterprise-grade security proxy that protects your package registries (npm, PyPI, Maven, Cargo, RubyGems, OpenVSX, NuGet, Go) by scanning packages with Socket's security API in real-time to block malicious packages before they reach your systems.

Supported Registries

  • npm (JavaScript/Node.js) - registry.npmjs.org
  • PyPI (Python) - pypi.org
  • Maven (Java) - repo1.maven.org
  • Cargo (Rust) - crates.io
  • RubyGems (Ruby) - rubygems.org
  • OpenVSX (VS Code Extensions) - open-vsx.org
  • NuGet (.NET) - nuget.org
  • Go (Go Modules) - proxy.golang.org
  • Conda (Python/R/etc.) - conda.anaconda.org (treated as PyPI until native support)

Key Features

Real-time Security - Blocks malicious packages before installation
Multi-Registry - Protects all 8 major package ecosystems
Flexible Routing - Domain-based or path-based routing
Auto-Discovery - Sync routes from Artifactory/Nexus automatically
High Performance - Intelligent caching with Redis support
Enterprise Ready - Outbound proxy, custom CAs, Splunk logging
Zero Config - Works with public registries out-of-the-box

Installation Methods

Socket Registry Firewall can be deployed in two ways:

  1. Pre-built Docker Image (Recommended) - Pull and run the official image
  2. Tarball Installation - Build your own image using the firewall tarball (for air-gapped or custom environments)

Quick Start (Pre-built Image)

1. Get Socket API Key

  1. Sign up at Socket.dev
  2. Go to Settings → API Keys
  3. Create API key with scopes: packages, entitlements:list

2. Set API Token

# Create .env file with your Socket API token
cat > .env <<EOF
SOCKET_SECURITY_API_TOKEN=your-api-key-here
EOF

Or export it in your shell:

export SOCKET_SECURITY_API_TOKEN=your-api-key-here

3. Create Docker Compose File

Create a docker-compose.yml:

services:
  socket-firewall:
    image: socketdev/socket-registry-firewall:latest
    ports:
      - "8080:8080"   # HTTP (redirects to HTTPS)
      - "8443:8443"   # HTTPS
    environment:
      # Required: Socket.dev API token
      - SOCKET_SECURITY_API_TOKEN=${SOCKET_SECURITY_API_TOKEN}
    volumes:
      # Configuration file
      - ./socket.yml:/app/socket.yml:ro
      # SSL certificates directory
      - ./ssl:/etc/nginx/ssl
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-fk", "https://localhost:8443/health"]
      interval: 30s
      timeout: 10s
      retries: 3

Create a minimal socket.yml:

# Minimal configuration - uses defaults for all public registries
# Access registries at: https://localhost:8443/npm/, /pypi/, /maven/, etc.

socket:
  api_url: https://api.socket.dev

# Set internal container ports the firewall will bind to
ports:
  http: 8080
  https: 8443

path_routing:
  enabled: true
  domain: sfw.your_company.com
  routes:
    - path: /npm
      upstream: https://registry.npmjs.org
      registry: npm
  
# Optional: Customize performance settings
nginx:
  worker_processes: 2
  worker_connections: 4096

4. Add host entry (edit /etc/hosts)

sudo sh -c 'printf "127.0.0.1   sfw.your_company.com\n::1         sfw.your_company.com\n" >> /etc/hosts'

5. Pull the Firewall from Docker

docker pull socketdev/socket-registry-firewall

6. Start the Firewall

docker compose up -d

That's it! The firewall is now protecting the npm registry at http://sfw.your_company.com:8080/npm/.


Alternative: Tarball Installation

For air-gapped environments, custom base images, or when you need to build your own container, Socket provides the firewall as a tarball that can be extracted into any OpenResty-based image.

When to Use Tarball Installation

  • Air-gapped environments - No access to Docker Hub
  • Custom base images - Need specific OpenResty version or OS distribution
  • Security requirements - Must build from source in your own registry
  • Custom modifications - Need to add additional tools or configurations

Prerequisites

  1. Obtain the tarball from Socket (e.g., socket-firewall-1.1.94.arm64.tgz)
  2. OpenResty base image - Compatible with openresty/openresty:1.27.1.2-11-alpine or similar

Installation Steps

1. Create Dockerfile

Create a Dockerfile in your project directory:

FROM openresty/openresty:1.27.1.2-11-alpine

# Copy and extract the Socket Firewall tarball
COPY socket-firewall-1.1.94.arm64.tgz /app/install/socket-firewall-1.1.94.arm64.tgz
COPY entrypoint.sh /app/entrypoint.sh

RUN chmod +x /app/entrypoint.sh \
  && tar -xzf /app/install/socket-firewall-1.1.94.arm64.tgz -C /

# Install basic dependencies
RUN apk add --no-cache curl ca-certificates git openssl bash && \
    # Prefer IPv4 over IPv6 to avoid upstream IPv6 connection attempts
    printf 'precedence ::ffff:0:0/96  100\n' >> /etc/gai.conf || true

# Install lua-resty libraries
RUN cd /tmp && \
    # Install lua-resty-http
    git clone https://github.com/ledgetech/lua-resty-http.git && \
    cd lua-resty-http && \
    cp -r lib/resty/* /usr/local/openresty/lualib/resty/ && \
    cd /tmp && \
    # Install lua-resty-openssl (needed for HTTPS)
    git clone https://github.com/fffonion/lua-resty-openssl.git && \
    cd lua-resty-openssl && \
    cp -r lib/resty/* /usr/local/openresty/lualib/resty/ && \
    cd /tmp && \
    # Install lua-resty-redis (needed for Redis caching)
    git clone https://github.com/openresty/lua-resty-redis.git && \
    cd lua-resty-redis && \
    cp lib/resty/redis.lua /usr/local/openresty/lualib/resty/ && \
    cd / && \
    rm -rf /tmp/lua-resty-http /tmp/lua-resty-openssl /tmp/lua-resty-redis

WORKDIR /app

ENTRYPOINT ["/app/entrypoint.sh"]

Note: Adjust the tarball filename to match your version and architecture (e.g., socket-firewall-1.1.94.amd64.tgz for x86_64).

2. Create Entrypoint Script

Download the entrypoint.sh script from Socket (provided with the tarball package) or request it from Socket support.

Place it in your project directory and make it executable:

chmod +x entrypoint.sh

The entrypoint script handles:

  • Configuration generation using socket-proxy-config-tool
  • Environment variable loading
  • Nginx configuration validation
  • Auto-discovery daemon startup (if configured)
  • Nginx process management

3. Create Docker Compose File

Create a docker-compose.yml for the tarball-based installation:

services:
  socket-firewall:
    build:
      context: .
      dockerfile: Dockerfile
    image: socketdev/socket-registry-firewall-tar:latest
    ports:
      - "8085:8080"   # HTTP (redirects to HTTPS)
      - "8445:8443"   # HTTPS
    environment:
      # Required: Socket.dev API token
      - SOCKET_SECURITY_API_TOKEN=${SOCKET_SECURITY_API_TOKEN}
    volumes:
      # Configuration file
      - ./socket.yml:/app/socket.yml:ro
      # SSL certificates directory
      - ./ssl:/etc/nginx/ssl
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-fk", "https://localhost:8443/health"]
      interval: 30s
      timeout: 10s
      retries: 1

Note: Different ports (8085/8445) are used in this example to avoid conflicts if running both methods simultaneously.

4. Build and Start

# Build the image
docker compose build

# Start the firewall
docker compose up -d

# View logs
docker compose logs -f socket-firewall

Tarball Contents

The Socket Firewall tarball includes:

  • /usr/local/bin/socket-proxy-config-tool - Configuration generation tool
  • /usr/local/openresty/lualib/socket/*.lua - Lua modules for package parsing and security checks
  • /usr/local/openresty/nginx/conf/snippets/ - Nginx configuration snippets
  • Supporting files for all 8 ecosystems (npm, PyPI, Maven, Cargo, RubyGems, OpenVSX, NuGet, Go)

The tarball extracts to standard OpenResty paths, making it compatible with any OpenResty-based image.

Customization Options

When using tarball installation, you can:

  • Use different base images: Change the FROM line to use specific OpenResty versions or distributions
  • Add custom tools: Install additional packages in the RUN command
  • Modify entrypoint: Customize the entrypoint script for your environment
  • Layer scanning: Add image scanning tools in your build pipeline
  • Internal registries: Push built images to your private container registry

Verification

After starting the firewall, verify it's working:

# Check health endpoint
curl -k https://localhost:8445/health

# Expected response:
{"status":"healthy","version":"1.1.94"}

# View startup logs
docker compose logs socket-firewall | grep -i "socket firewall"

Configuration (Both Methods)

Both the pre-built image and tarball installation use the same socket.yml configuration file format.

Testing It Works

Test npm:

# Configure npm to use the firewall
npm config set registry http://sfw.your_company.com:8080/npm/
npm config set strict-ssl false  # Only for self-signed certs

# Install a package
npm install lodash --loglevel verbose

# Try to install a malicious package and watch Socket Firewall block the package.
npm install lodahs

Additional ecosystem samples

  • Add more ecosystems into the socket.yml, then test with these common language samples below.

Test pip:

# Configure pip to use the firewall
pip config set global.index-url https://localhost:8443/pypi/simple
pip config set global.trusted-host "localhost"

# Install a package
pip install requests

Test Maven:

# Add to ~/.m2/settings.xml
cat > ~/.m2/settings.xml <<'EOF'
<settings>
  <mirrors>
    <mirror>
      <id>socket-firewall</id>
      <url>https://localhost:8443/maven</url>
      <mirrorOf>*</mirrorOf>
    </mirror>
  </mirrors>
</settings>
EOF

# Build your project
mvn install -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true

Test Gradle:

edit your settings.gradle:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) // or FAIL_ON_PROJECT_REPOS
    repositories {
        maven { url "https://localhost:8443/maven" }
    }
}

Advanced Configuration

Basic: Custom Domains

Create socket.yml for custom domains:

registries:
  npm:
    domains:
      - npm.company.com
  pypi:
    domains:
      - pypi.company.com
  maven:
    domains:
      - maven.company.com

Advanced: Path Routing (Artifactory/Nexus)

Single domain with path prefixes:

path_routing:
  enabled: true
  domain: firewall.company.com
  
  routes:
    - path: /npm
      upstream: https://registry.npmjs.org
      registry: npm
    
    - path: /pypi
      upstream: https://pypi.org
      registry: pypi
    
    - path: /maven
      upstream: https://repo1.maven.org/maven2
      registry: maven

Enterprise: Auto-Discovery from Artifactory/Nexus

Automatically sync repository routes:

path_routing:
  enabled: true
  domain: firewall.company.com
  mode: nexus  # or 'artifactory'
  
  private_registry:
    api_url: https://nexus.company.com
    api_key: your-nexus-api-token
    interval: 5m  # Auto-sync every 5 minutes
    
    # Optional filters
    include_pattern: ".*"
    exclude_pattern: "(tmp|test)-.*"

Routes update automatically when you add/remove repositories - no manual configuration!

See docs/AUTO-DISCOVERY.md for details.

SSL/TLS Certificates

Option 1: Use Provided Self-Signed Certificates

The firewall auto-generates self-signed certificates on first run. Trust them:

macOS:

sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain ssl/fullchain.pem

Linux:

sudo cp ssl/fullchain.pem /usr/local/share/ca-certificates/socket-firewall.crt
sudo update-ca-certificates

Option 2: Use Your Own Certificates

Place your certificates in the ssl/ directory:

cp /path/to/cert.pem ssl/fullchain.pem
cp /path/to/key.pem ssl/privkey.pem

Option 3: Generate Custom Self-Signed Cert

mkdir -p ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout ssl/privkey.pem \
  -out ssl/fullchain.pem \
  -subj "/CN=*.company.com" \
  -addext "subjectAltName=DNS:firewall.company.com,DNS:npm.company.com,DNS:pypi.company.com"

Common Configuration Options

Outbound Proxy

Route all upstream traffic through a corporate proxy:

socket:
  outbound_proxy: http://proxy.company.com:3128
  no_proxy: localhost,127.0.0.1,internal.company.com

SSL Verification (Corporate MITM Proxy)

socket:
  outbound_proxy: http://proxy.company.com:3128
  
  # Verify SSL with corporate CA
  api_ssl_verify: true
  api_ssl_ca_cert: /path/to/corporate-ca.crt
  
  # Apply same CA to upstream registries
  # (or set upstream_ssl_verify separately if different)

Redis Caching (Multi-Instance)

For distributed deployments:

redis:
  enabled: true
  host: redis.company.com
  port: 6379
  password: your-redis-password
  ttl: 86400  # 24 hours

Performance Tuning

# Match worker_processes to CPU cores
worker_processes: 4
worker_connections: 8192

proxy:
  connect_timeout: 60
  send_timeout: 60
  read_timeout: 60

Fail-Safe Behavior

socket:
  fail_open: true  # Allow packages if Socket API is down (default)
  # fail_open: false  # Block all packages if Socket API is down

Environment Variables

Override configuration via environment variables:

# Core settings
SOCKET_SECURITY_API_TOKEN=your-api-key     # Required
SOCKET_API_URL=https://api.socket.dev      # Default
SOCKET_CACHE_TTL=600                       # Seconds, default: 600
SOCKET_FAIL_OPEN=true                      # Allow on API error

# Ports
HTTP_PORT=8080                             # Default: 8080
HTTPS_PORT=8443                            # Default: 8443

# Redis (optional)
REDIS_ENABLED=true
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=secret

# Proxy (optional)
SOCKET_OUTBOUND_PROXY=http://proxy:3128
SOCKET_NO_PROXY=localhost,127.0.0.1

Health Checks

# Health endpoint (no auth required)
curl https://localhost:8443/health

# Expected response:
# {"status":"healthy","version":"1.1.23"}

Monitoring & Logging

View Logs

# All logs
docker compose logs -f socket-firewall

# Errors only
docker compose logs socket-firewall | grep -i error

# Security events
docker compose logs socket-firewall | grep -i block

Splunk Integration

Forward security events to Splunk:

splunk:
  enabled: true
  hec_url: https://splunk.company.com:8088/services/collector/event
  hec_token: your-splunk-hec-token
  index: security
  source: socket-firewall

See docs/SPLUNK.md for details.

Troubleshooting

Docker Container Won't Start

# Check logs
docker compose logs socket-firewall

# Verify environment variables
docker compose exec socket-firewall env | grep SOCKET

# Test config generation
docker compose exec socket-firewall socket-proxy-config-tool generate --config /app/socket.yml

Package Installation Fails

# Check if package is blocked
docker compose logs socket-firewall | grep -i block

# Verify firewall is reachable
curl -I https://localhost:8443/health

# Test upstream connectivity from container
docker compose exec socket-firewall curl -I https://registry.npmjs.org

SSL Certificate Errors

# For testing, bypass SSL verification:

# npm
npm config set strict-ssl false

# pip
PIP_TRUSTED_HOST='localhost' pip install package

# Maven (add flags)
mvn install -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true

# For production, trust the CA certificate (see SSL/TLS section above)

Firewall Not Blocking Malicious Packages

# Verify API token is set
docker compose exec socket-firewall env | grep SOCKET_SECURITY_API_TOKEN

# Check API connectivity (from container)
docker compose exec socket-firewall curl https://api.socket.dev/v0/health

# Review fail_open setting
cat socket.yml | grep fail_open

Advanced Features

Metadata Filtering

Remove blocked/warned packages from registry metadata responses:

metadata_filtering:
  enabled: true
  filter_blocked: true   # Remove blocked packages
  filter_warn: false     # Keep warned packages (show warnings only)

Bulk PURL Lookup

Pre-cache security status for faster lookups:

bulk_purl_lookup:
  enabled: true
  batch_size: 5000  # PURLs per batch

External Routes File

For 50+ routes, use external file:

path_routing:
  enabled: true
  domain: firewall.company.com
  routes_file: /config/routes.yml

See docs/EXTERNAL-ROUTES.md for format.

Architecture

Client (npm/pip/mvn)
    ↓
Socket Firewall (this)
    ↓
Socket.dev API (security check)
    ↓
Upstream Registry (npmjs.org, pypi.org, etc.)

Request Flow:

  1. Client requests package from firewall
  2. Firewall extracts package name/version
  3. Firewall checks Socket API for security issues
  4. If safe: proxy to upstream and return package
  5. If malicious: return 403 Forbidden with reason

Documentation

Examples

Example 1: Protect Public Registries

# Minimal config - no custom domains needed
# Just start with docker compose up -d
# Access at https://localhost:8443/npm/, /pypi/, /maven/, etc.

Example 2: Custom Domains for Each Registry

registries:
  npm:
    domains: [npm.company.com]
  pypi:
    domains: [pypi.company.com]
  maven:
    domains: [maven.company.com]
  cargo:
    domains: [cargo.company.com]
  rubygems:
    domains: [rubygems.company.com]
  openvsx:
    domains: [vsx.company.com]
  nuget:
    domains: [nuget.company.com]
  go:
    domains: [go.company.com]

Example 3: Single Domain for All Registries

path_routing:
  enabled: true
  domain: packages.company.com
  
  routes:
    - { path: /npm, upstream: https://registry.npmjs.org, registry: npm }
    - { path: /pypi, upstream: https://pypi.org, registry: pypi }
    - { path: /maven, upstream: https://repo1.maven.org/maven2, registry: maven }
    - { path: /cargo, upstream: https://index.crates.io, registry: cargo }
    - { path: /rubygems, upstream: https://rubygems.org, registry: rubygems }
    - { path: /openvsx, upstream: https://open-vsx.org, registry: openvsx }
    - { path: /nuget, upstream: https://api.nuget.org, registry: nuget }
    - { path: /go, upstream: https://proxy.golang.org, registry: go }

Example 4: Private Artifactory/Nexus

path_routing:
  enabled: true
  domain: firewall.company.com
  mode: artifactory  # or 'nexus'
  
  private_registry:
    api_url: https://artifactory.company.com/artifactory
    api_key: your-artifactory-api-key
    interval: 5m
    default_registry: maven  # Fallback for unknown repos

Support

License

Proprietary - Socket Security Inc.


Need help? Check docs/ for detailed guides or contact support@socket.dev

About

Release repository for the Socket Registry Firewall artifacts

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages