Skip to content

Commit e137d23

Browse files
Copilotphrocker
andcommitted
Implement SSH Server proxy with Sentrius safeguards integration
Co-authored-by: phrocker <1781585+phrocker@users.noreply.github.com>
1 parent 7e65ca7 commit e137d23

16 files changed

Lines changed: 1227 additions & 1 deletion

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<module>analytics</module>
2020
<module>ai-agent</module>
2121
<module>agent-launcher</module>
22+
<module>ssh-proxy</module>
2223
</modules>
2324
<properties>
2425
<java.version>17</java.version>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: sentrius-ssh-proxy
5+
labels:
6+
app: sentrius-ssh-proxy
7+
release: {{ .Release.Name }}
8+
spec:
9+
replicas: {{ .Values.replicaCount }}
10+
selector:
11+
matchLabels:
12+
app: sentrius-ssh-proxy
13+
template:
14+
metadata:
15+
labels:
16+
app: sentrius-ssh-proxy
17+
spec:
18+
containers:
19+
- name: sentrius-ssh-proxy
20+
image: "{{ .Values.sshproxy.image.repository }}:{{ .Values.sshproxy.image.tag }}"
21+
imagePullPolicy: {{ .Values.sshproxy.image.pullPolicy }}
22+
ports:
23+
- containerPort: {{ .Values.sshproxy.port }}
24+
name: ssh
25+
- containerPort: 8090
26+
name: http
27+
env:
28+
- name: SENTRIUS_SSH_PROXY_ENABLED
29+
value: "{{ .Values.sshproxy.enabled }}"
30+
- name: SENTRIUS_SSH_PROXY_PORT
31+
value: "{{ .Values.sshproxy.port }}"
32+
- name: SENTRIUS_SSH_PROXY_TARGET_SSH_DEFAULT_HOST
33+
value: "{{ .Values.sshproxy.targetSsh.defaultHost }}"
34+
- name: SENTRIUS_SSH_PROXY_TARGET_SSH_DEFAULT_PORT
35+
value: "{{ .Values.sshproxy.targetSsh.defaultPort }}"
36+
resources:
37+
{{- toYaml .Values.sshproxy.resources | nindent 12 }}
38+
livenessProbe:
39+
httpGet:
40+
path: /actuator/health
41+
port: http
42+
initialDelaySeconds: 30
43+
periodSeconds: 10
44+
readinessProbe:
45+
httpGet:
46+
path: /actuator/health
47+
port: http
48+
initialDelaySeconds: 5
49+
periodSeconds: 5
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: sentrius-ssh-proxy
5+
labels:
6+
app: sentrius-ssh-proxy
7+
release: {{ .Release.Name }}
8+
spec:
9+
type: {{ .Values.sshproxy.serviceType }}
10+
ports:
11+
- port: {{ .Values.sshproxy.port }}
12+
targetPort: {{ .Values.sshproxy.port }}
13+
protocol: TCP
14+
name: ssh
15+
{{- if and (eq .Values.sshproxy.serviceType "NodePort") .Values.sshproxy.nodePort }}
16+
nodePort: {{ .Values.sshproxy.nodePort }}
17+
{{- end }}
18+
- port: 8090
19+
targetPort: 8090
20+
protocol: TCP
21+
name: http
22+
selector:
23+
app: sentrius-ssh-proxy

sentrius-chart/values.yaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,4 +365,21 @@ neo4j:
365365
NEO4J_server_config_strict__validation__enabled: "true"
366366

367367
adminer:
368-
enabled: false
368+
enabled: false
369+
370+
# SSH Proxy configuration
371+
sshproxy:
372+
enabled: true
373+
image:
374+
repository: sentrius-ssh-proxy
375+
tag: tag
376+
pullPolicy: IfNotPresent
377+
port: 2222
378+
serviceType: ClusterIP
379+
nodePort: 30022 # Only used if serviceType is NodePort
380+
resources: {}
381+
targetSsh:
382+
defaultHost: "localhost"
383+
defaultPort: 22
384+
connectionTimeout: 30000
385+
keepAliveInterval: 60000

ssh-proxy/README.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Sentrius SSH Proxy Server
2+
3+
The SSH Proxy Server provides an SSH server that applies the same safeguards seen in Sentrius UI to any SSH client. Commands are intercepted and processed through Sentrius's trigger-based security system, with responses provided inline in the terminal.
4+
5+
## Features
6+
7+
- **SSH Server**: Standard SSH server accepting connections from any SSH client
8+
- **Inline Security Responses**: Security policy responses shown directly in the terminal
9+
- **Trigger Integration**: Applies the same trigger-based safeguards as the Sentrius UI
10+
- **Command Filtering**: Basic command filtering with DENY, WARN, and other actions
11+
- **Terminal-Friendly Messages**: Colored, formatted responses optimized for terminal display
12+
13+
## Configuration
14+
15+
The SSH proxy can be configured via application properties:
16+
17+
```properties
18+
# SSH Proxy Configuration
19+
sentrius.ssh-proxy.enabled=true
20+
sentrius.ssh-proxy.port=2222
21+
sentrius.ssh-proxy.host-key-path=/tmp/ssh-proxy-hostkey.ser
22+
sentrius.ssh-proxy.max-concurrent-sessions=100
23+
24+
# Target SSH Configuration
25+
sentrius.ssh-proxy.target-ssh.default-host=localhost
26+
sentrius.ssh-proxy.target-ssh.default-port=22
27+
sentrius.ssh-proxy.target-ssh.connection-timeout=30000
28+
sentrius.ssh-proxy.target-ssh.keep-alive-interval=60000
29+
```
30+
31+
## Usage
32+
33+
1. **Start the SSH Proxy Server**:
34+
```bash
35+
mvn spring-boot:run -pl ssh-proxy
36+
```
37+
38+
2. **Connect with any SSH client**:
39+
```bash
40+
ssh -p 2222 username@localhost
41+
```
42+
43+
3. **Commands are processed through Sentrius safeguards**:
44+
- Dangerous commands like `rm -rf` are blocked with red error messages
45+
- Warning commands like `sudo` show yellow warning messages
46+
- All responses appear inline in your terminal
47+
48+
## Security Responses
49+
50+
The SSH proxy translates Sentrius trigger actions into terminal-friendly responses:
51+
52+
- **DENY_ACTION**: Red "COMMAND BLOCKED" message
53+
- **WARN_ACTION**: Yellow "WARNING" message
54+
- **RECORD_ACTION**: Green "RECORDING" notification
55+
- **PROMPT_ACTION**: Blue interactive prompt
56+
- **JIT_ACTION**: Yellow "JUST-IN-TIME ACCESS" message
57+
58+
## Built-in Commands
59+
60+
- `help` - Show available commands
61+
- `status` - Show session status
62+
- `exit` - Close SSH session
63+
64+
## Helm Deployment
65+
66+
The SSH proxy is included in the Sentrius Helm chart:
67+
68+
```yaml
69+
sshproxy:
70+
enabled: true
71+
port: 2222
72+
serviceType: ClusterIP
73+
targetSsh:
74+
defaultHost: "target-ssh-server"
75+
defaultPort: 22
76+
```
77+
78+
## Architecture
79+
80+
- **SshProxyServerService**: Main SSH server using Apache SSHD
81+
- **SshProxyShellHandler**: Manages individual SSH sessions
82+
- **InlineTerminalResponseService**: Formats security responses for terminal
83+
- **SshCommandProcessor**: Applies trigger-based command filtering
84+
85+
## Future Enhancements
86+
87+
- Integration with full Sentrius session management
88+
- Command forwarding to actual target SSH servers
89+
- Interactive prompt handling for complex security decisions
90+
- Integration with Sentrius user authentication system
91+
- Enhanced trigger rule configuration

ssh-proxy/demo.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
3+
# Sentrius SSH Proxy Demo Script
4+
# This script demonstrates the SSH proxy functionality
5+
6+
echo "=== Sentrius SSH Proxy Server Demo ==="
7+
echo "This script shows how the SSH proxy applies safeguards to SSH commands"
8+
echo ""
9+
10+
# Start SSH proxy in background
11+
echo "Starting SSH Proxy Server..."
12+
cd /home/runner/work/Sentrius/Sentrius/ssh-proxy
13+
14+
# Create a simple test to show trigger responses
15+
echo "Testing trigger response formatting..."
16+
17+
# Test the terminal response service
18+
mvn exec:java -Dexec.mainClass="io.sentrius.sso.sshproxy.SshProxyApplication" \
19+
-Dexec.args="--spring.profiles.active=demo" \
20+
-Dsentrius.ssh-proxy.port=2222 \
21+
-Dsentrius.ssh-proxy.enabled=true &
22+
23+
SSH_PID=$!
24+
25+
echo "SSH Proxy started with PID: $SSH_PID"
26+
echo "You can now connect with: ssh -p 2222 testuser@localhost"
27+
echo ""
28+
echo "Try these commands to see safeguards in action:"
29+
echo " - 'sudo rm -rf /' (will be BLOCKED)"
30+
echo " - 'sudo ls' (will show WARNING)"
31+
echo " - 'ls' (will be allowed)"
32+
echo " - 'help' (shows built-in commands)"
33+
echo " - 'exit' (closes session)"
34+
echo ""
35+
echo "Press Ctrl+C to stop the demo"
36+
37+
# Wait for user to stop
38+
trap "kill $SSH_PID 2>/dev/null; echo 'SSH Proxy stopped'; exit 0" INT
39+
wait

ssh-proxy/pom.xml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>io.sentrius</groupId>
9+
<artifactId>sentrius</artifactId>
10+
<version>1.0.0-SNAPSHOT</version>
11+
</parent>
12+
13+
<artifactId>ssh-proxy</artifactId>
14+
<packaging>jar</packaging>
15+
<name>ssh-proxy</name>
16+
<description>SSH proxy server that applies Sentrius safeguards</description>
17+
18+
<properties>
19+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20+
<maven.compiler.source>17</maven.compiler.source>
21+
<maven.compiler.target>17</maven.compiler.target>
22+
</properties>
23+
24+
<dependencies>
25+
<!-- Sentrius core dependencies -->
26+
<dependency>
27+
<groupId>io.sentrius</groupId>
28+
<artifactId>sentrius-core</artifactId>
29+
<version>1.0.0-SNAPSHOT</version>
30+
</dependency>
31+
<dependency>
32+
<groupId>io.sentrius</groupId>
33+
<artifactId>sentrius-dataplane</artifactId>
34+
<version>1.0.0-SNAPSHOT</version>
35+
</dependency>
36+
37+
<!-- Spring Boot -->
38+
<dependency>
39+
<groupId>org.springframework.boot</groupId>
40+
<artifactId>spring-boot-starter</artifactId>
41+
</dependency>
42+
<dependency>
43+
<groupId>org.springframework.boot</groupId>
44+
<artifactId>spring-boot-starter-web</artifactId>
45+
</dependency>
46+
47+
<!-- SSH Library -->
48+
<dependency>
49+
<groupId>com.github.mwiede</groupId>
50+
<artifactId>jsch</artifactId>
51+
<version>${jsch-version}</version>
52+
</dependency>
53+
54+
<!-- Apache SSHD for SSH server -->
55+
<dependency>
56+
<groupId>org.apache.sshd</groupId>
57+
<artifactId>sshd-core</artifactId>
58+
<version>2.12.0</version>
59+
</dependency>
60+
<dependency>
61+
<groupId>org.apache.sshd</groupId>
62+
<artifactId>sshd-sftp</artifactId>
63+
<version>2.12.0</version>
64+
</dependency>
65+
66+
<!-- Lombok -->
67+
<dependency>
68+
<groupId>org.projectlombok</groupId>
69+
<artifactId>lombok</artifactId>
70+
<scope>provided</scope>
71+
</dependency>
72+
73+
<!-- Testing -->
74+
<dependency>
75+
<groupId>org.springframework.boot</groupId>
76+
<artifactId>spring-boot-starter-test</artifactId>
77+
<scope>test</scope>
78+
</dependency>
79+
</dependencies>
80+
81+
<build>
82+
<plugins>
83+
<plugin>
84+
<groupId>org.springframework.boot</groupId>
85+
<artifactId>spring-boot-maven-plugin</artifactId>
86+
<configuration>
87+
<excludes>
88+
<exclude>
89+
<groupId>org.projectlombok</groupId>
90+
<artifactId>lombok</artifactId>
91+
</exclude>
92+
</excludes>
93+
</configuration>
94+
</plugin>
95+
</plugins>
96+
</build>
97+
</project>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.sentrius.sso.sshproxy;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.context.annotation.ComponentScan;
6+
7+
@SpringBootApplication
8+
@ComponentScan(basePackages = {
9+
"io.sentrius.sso.sshproxy",
10+
"io.sentrius.sso.core",
11+
"io.sentrius.sso.automation"
12+
})
13+
public class SshProxyApplication {
14+
15+
public static void main(String[] args) {
16+
SpringApplication.run(SshProxyApplication.class, args);
17+
}
18+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.sentrius.sso.sshproxy.config;
2+
3+
import lombok.Data;
4+
import org.springframework.boot.context.properties.ConfigurationProperties;
5+
import org.springframework.stereotype.Component;
6+
7+
@Data
8+
@Component
9+
@ConfigurationProperties(prefix = "sentrius.ssh-proxy")
10+
public class SshProxyConfig {
11+
12+
private int port = 2222; // Default port for SSH proxy
13+
private String hostKeyPath = "/tmp/hostkey.ser";
14+
private boolean enabled = true;
15+
private int maxConcurrentSessions = 100;
16+
17+
// Target SSH configuration
18+
private TargetSsh targetSsh = new TargetSsh();
19+
20+
@Data
21+
public static class TargetSsh {
22+
private String defaultHost = "localhost";
23+
private int defaultPort = 22;
24+
private int connectionTimeout = 30000;
25+
private int keepAliveInterval = 60000;
26+
}
27+
}

0 commit comments

Comments
 (0)