proxy-bridge: add keyring-based HTTP CONNECT proxy bridge

This commit is contained in:
tke
2026-04-27 14:27:27 +02:00
parent 71bffc77ae
commit ac3245b78f
3 changed files with 161 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
const http = require('http');
const net = require('net');
const { execSync } = require('child_process');
const fs = require('fs');
// 1. CONFIGURATION
const PROXY_HOST = 'PROXY_HOST_PLACEHOLDER';
const PROXY_PORT = 8080;
// 2. FETCH SECRETS FROM KEYRING
let USER, PASS;
try {
// Read the username we saved during setup
USER = JSON.parse(fs.readFileSync('/opt/proxy-bridge/user.json')).username;
// Query the Ubuntu Keyring for the password associated with this user/service
PASS = execSync(`secret-tool lookup service proxy-bridge account ${USER}`).toString().trim();
if (!PASS) throw new Error("Password returned empty.");
} catch (e) {
console.error("CRITICAL: Could not retrieve credentials from keyring. Did you run setup.js?");
console.error(e.message);
process.exit(1);
}
// 3. GENERATE AUTH
const AUTH_HEADER = 'Basic ' + Buffer.from(`${USER}:${PASS}`).toString('base64');
const server = http.createServer();
server.on('connect', (req, clientSocket, head) => {
console.log(`--> Connecting to ${req.url}`);
const serverSocket = net.connect(PROXY_PORT, PROXY_HOST, () => {
serverSocket.write(`CONNECT ${req.url} HTTP/1.1\r\n` +
`Host: ${req.url}\r\n` +
`Proxy-Authorization: ${AUTH_HEADER}\r\n` +
`Proxy-Connection: Keep-Alive\r\n\r\n`);
serverSocket.write(head);
});
serverSocket.once('data', (data) => {
if (data.toString().includes('200')) {
clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
serverSocket.pipe(clientSocket);
clientSocket.pipe(serverSocket);
} else {
clientSocket.write(data);
}
});
serverSocket.on('error', () => clientSocket.end());
clientSocket.on('error', () => serverSocket.end());
});
server.listen(8888, '127.0.0.1', () => {
console.log('Bridge active on http://127.0.0.1:8888 (Auth via Keyring)');
});
+70
View File
@@ -0,0 +1,70 @@
#!/bin/bash
# Ensure the script is NOT run as root, so the user-level systemd service configures correctly
if [ "$EUID" -eq 0 ]; then
echo "❌ Please run this script as your standard user, not as root."
echo "The script will prompt for sudo access automatically when needed."
exit 1
fi
echo "=== Proxy Bridge Installer ==="
# 1. Verify files exist
if [ ! -f "bridge.js" ] || [ ! -f "setup.js" ]; then
echo "❌ Error: bridge.js and/or setup.js not found in the current directory."
echo "Please place this script in the same folder as your Node.js scripts."
exit 1
fi
# 2. Install dependencies (requires sudo)
echo "--> Installing required system packages (libsecret-tools)..."
sudo apt-get update
sudo apt-get install -y libsecret-tools
# 3. Setup application directory (requires sudo)
echo "--> Creating /opt/proxy-bridge directory..."
sudo mkdir -p /opt/proxy-bridge
sudo chown -R $USER:$USER /opt/proxy-bridge
# 4. Copy files
echo "--> Copying scripts to /opt/proxy-bridge..."
cp bridge.js /opt/proxy-bridge/
cp setup.js /opt/proxy-bridge/
# 5. Setup User-Level systemd Service
echo "--> Configuring user-level systemd service..."
mkdir -p ~/.config/systemd/user/
cat <<EOF > ~/.config/systemd/user/proxy-bridge.service
[Unit]
Description=Dumb Pipe Proxy Bridge (Keyring Auth)
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/node /opt/proxy-bridge/bridge.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
EOF
# 6. Enable the service
echo "--> Reloading systemd and enabling service..."
systemctl --user daemon-reload
systemctl --user enable proxy-bridge.service
echo ""
echo "✅ Installation Complete!"
echo "=================================================="
echo "Next Steps:"
echo "1. Run the interactive setup to store your proxy credentials:"
echo " node /opt/proxy-bridge/setup.js"
echo ""
echo "2. Start the background service:"
echo " systemctl --user start proxy-bridge.service"
echo ""
echo "3. Check the logs to ensure it's running smoothly:"
echo " journalctl --user -u proxy-bridge.service -f"
echo "=================================================="
+34
View File
@@ -0,0 +1,34 @@
const readline = require('readline');
const { execSync } = require('child_process');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
console.log("=== Proxy Bridge Keyring Setup ===");
rl.question('Enter your corporate username: ', (user) => {
rl.question('Enter your corporate password: ', (pass) => {
try {
// Securely store the password in the Ubuntu Keyring using secret-tool
// We use standard input to pass the password so it doesn't appear in process lists
execSync(`secret-tool store --label="Proxy Bridge Credentials" service proxy-bridge account ${user}`, {
input: pass
});
// Store the username in a local config just so the bridge knows WHICH account to look up
require('fs').writeFileSync('/opt/proxy-bridge/user.json', JSON.stringify({ username: user }));
console.log("\n✅ Credentials successfully stored in the system keyring.");
} catch (error) {
console.error("\n❌ Failed to store credentials in keyring:", error.message);
}
rl.close();
});
// Hide typing for password (basic implementation)
rl._writeToOutput = function _writeToOutput(stringToWrite) {
if (rl.history.length === 0) rl.output.write("*");
};
});