An open API service indexing awesome lists of open source software.

https://github.com/socketdev/socket-registry-firewall

Release repository for the Socket Registry Firewall artifacts
https://github.com/socketdev/socket-registry-firewall

Last synced: about 1 month ago
JSON representation

Release repository for the Socket Registry Firewall artifacts

Awesome Lists containing this project

README

          

# 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.) - `repo.anaconda.com/pkgs/main` *(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](https://socket.dev/)
2. Go to [Settings → API Keys](https://socket.dev/dashboard/organization/settings/api-keys)
3. Create API key with scopes: `packages`, `entitlements:list`

### 2. Set API Token

```bash
# Create .env file with your Socket API token
cat > .env <> /etc/hosts'
```

### 5. Pull the Firewall from Docker
```
docker pull socketdev/socket-registry-firewall
```

### 6. Start the Firewall

```bash
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.29.2.4-alpine` or similar

### Installation Steps

#### 1. Create Dockerfile

Create a `Dockerfile` in your project directory:

```dockerfile
FROM openresty/openresty:1.29.2.4-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:

```bash
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:

```yaml
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

```bash
# 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:

```bash
# 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:**
```bash
# 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:**
```bash
# 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:**
```bash
# Add to ~/.m2/settings.xml
cat > ~/.m2/settings.xml <<'EOF'



socket-firewall
https://localhost:8443/maven
*

EOF

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

**Test Gradle:**

edit your `settings.gradle`:
```groovy
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:

```yaml
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:

```yaml
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:

```yaml
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](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:**
```bash
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain ssl/fullchain.pem
```

**Linux:**
```bash
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:

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

### Option 3: Generate Custom Self-Signed Cert

```bash
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:

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

### SSL Verification (Corporate MITM Proxy)

```yaml
socket:
outbound_proxy: http://proxy.company.com:3128

# Verify SSL with corporate CA (default: false)
api_ssl_verify: true
api_ssl_ca_cert: /path/to/corporate-ca.crt

# Apply same CA to upstream registries (defaults to api_ssl_verify)
# (or set upstream_ssl_verify separately if different)
```

### Redis Caching (Multi-Instance)

For distributed deployments:

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

### Performance Tuning

```yaml
# 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

```yaml
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:

```bash
# 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

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

# Expected response (plain text):
# SocketFirewall/1.1.23 - Health OK - npm (registry.npmjs.org)
```

## Monitoring & Logging

### View Logs

```bash
# 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:

```yaml
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](docs/SPLUNK.md) for details.

## Troubleshooting

### Docker Container Won't Start

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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:

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

### External Routes File

For 50+ routes, use external file:

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

See [docs/EXTERNAL-ROUTES.md](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

- **Getting Started**: This file
- **Auto-Discovery**: [docs/AUTO-DISCOVERY.md](docs/AUTO-DISCOVERY.md)
- **External Routes**: [docs/EXTERNAL-ROUTES.md](docs/EXTERNAL-ROUTES.md)
- **Redis Caching**: [docs/REDIS.md](docs/REDIS.md)
- **Splunk Integration**: [docs/SPLUNK.md](docs/SPLUNK.md)
- **Artifactory Auth**: [docs/ARTIFACTORY-AUTH.md](docs/ARTIFACTORY-AUTH.md)

## Examples

### Example 1: Protect Public Registries

```yaml
# 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

```yaml
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

```yaml
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

```yaml
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

- **GitHub Issues**: https://github.com/SocketDev/socket-nginx-firewall/issues
- **Email**: support@socket.dev
- **Documentation**: https://docs.socket.dev
- **Socket Dashboard**: https://socket.dev/dashboard

## License

Proprietary - Socket Security Inc.

---

**Need help?** Check [docs/](docs/) for detailed guides or contact support@socket.dev