A comprehensive SSH key management solution with multi-tenant architecture that enables organizations to centrally manage SSH access to their servers.
- Multi-Unit System: Complete isolation between different organizations
- Permission-based Access Control: Granular permissions (manage_users, manage_servers, manage_ssh_keys, view_audit_logs, export_audit_logs)
- Server Management: Central management of SSH servers with registration codes
- SSH Key Management: Secure storage and management of SSH keys
- AuthorizedKeysCommand Integration: Seamless integration into SSH servers
- Comprehensive Audit Logging: Full activity tracking with export capabilities
- RESTful API: Complete REST API for all functions
- Server-side Rendered: Responsive design with TailwindCSS
- Dashboard: Overview of servers, users, SSH keys and recent activity
- Server Management: Interface for server registration and configuration
- SSH Key Management: User-friendly key management
- User Administration: Admin interface for user management
- Audit Log Viewer: Comprehensive audit log interface with statistics
- Symfony Framework: Modern PHP framework with Doctrine ORM
- MySQL/MariaDB: Robust data persistence
- Automated Server Registration: Bash script for easy server integration
- Namespace: Shellock\ (previously App\)
- PHP 8.4 or higher
- Composer
- MySQL/MariaDB
- Node.js & npm (for frontend assets)
- Git
- For server registration: curl, jq, systemd
git clone <repository-url>
cd ssh-server# Install PHP dependencies
composer install
# Install Node.js dependencies
npm installcp .env .env.local
# Edit .env.local with your database credentialsphp bin/console doctrine:database:create
php bin/console doctrine:migrations:migrate# Build assets
npm run build
# Start development server
symfony server:start
# or
php -S localhost:8000 -t public/The application will be available at:
- Application: http://localhost:8000
- Register First User: Open http://localhost:8000/register and create the first admin account
- Configure Unit: The first registered user automatically becomes admin of the new unit
- Add Servers: Create servers in the web interface and receive registration codes
Run the provided script on the target server:
# Download script directly with registration code
curl -sSL "https://your-domain.com/api/server-setup/script/<REGISTRATION_CODE>" -o register-server.sh
chmod +x register-server.sh
# Run the script
sudo ./register-server.shExample:
curl -sSL "https://shellock.example.com/api/server-setup/script/abc123-def456-ghi789" -o register-server.sh
chmod +x register-server.sh
sudo ./register-server.shOr even simpler with one-liner:
curl -sSL "https://shellock.example.com/api/server-setup/script/abc123-def456-ghi789" | sudo bash- Server Registration: Connection to backend and confirmation of registration
- SSH Configuration: Automatic configuration of SSH daemon settings
- AuthorizedKeysCommand Setup: Installation of key retrieval script
- Health Monitoring: Setup of systemd service for health checks
- Service Restart: Restart of SSH daemon with new configuration
Available Permissions:
manage_users: Create, edit, delete usersmanage_servers: Add and configure serversmanage_ssh_keys: Manage SSH keysview_audit_logs: View audit logs and activityexport_audit_logs: Export audit logs for compliance
Permission Assignment: Permissions are assigned individually to users and checked throughout the application interface and API endpoints.
- Unit Isolation: Users can only access servers from their own unit
- Server-User Mapping: Each server has defined system users (e.g. root, deploy)
- Individual Access: Admins can grant users access individually or in groups
- SSH Key Activation: Keys can be temporarily disabled
# Install dependencies
composer install
# Database migrations
php bin/console doctrine:migrations:migrate
# Run tests
php bin/phpunit
# Code coverage
php bin/phpunit --coverage-html coverage
# Start development server
symfony server:start# Install dependencies
npm install
# Watch and build assets
npm run watch
# Build for production
npm run buildThe REST API provides the following main endpoints:
GET /api/servers- List all servers of the unitPOST /api/servers- Create new serverGET /api/servers/{id}- Get server detailsPOST /api/servers/{id}/users- Add server userPOST /api/servers/register/{code}- Register server
GET /api/user/ssh-keys- List own SSH keysPOST /api/user/ssh-keys- Add new SSH keyDELETE /api/user/ssh-keys/{id}- Delete SSH keyGET /api/ssh-keys/{serverId}/{username}- Retrieve keys for server (AuthorizedKeysCommand)
GET /api/users- List users in unitPOST /api/users- Create new userPUT /api/users/{id}- Update userDELETE /api/users/{id}- Delete user
GET /api/audit-logs- List audit logs with filteringGET /api/audit-logs/statistics- Get audit log statisticsGET /api/audit-logs/export- Export audit logs
# All tests
php bin/phpunit
# Unit tests only
php bin/phpunit tests/Unit
# Integration tests only
php bin/phpunit tests/Integration
# With coverage
php bin/phpunit --coverage-html coverageUnit Tests:
- Entity tests (User, Server, SshKey, AuditLog, etc.)
- Service tests (UserManagementService, ServerManagementService, etc.)
- DTO tests (Data Transfer Objects)
Integration Tests:
- API integration tests
- SSH key workflow tests
- Database integration tests
Functional Tests:
- Controller tests
- End-to-end functionality tests
- Authentication flow tests
- Unit Isolation: Complete data separation between units
- Session-based Authentication: Secure web authentication with Symfony Security
- Permission-based Access Control: Granular permission control with individual user permissions
- Centralized Key Management: No local authorized_keys files
- Real-time Key Retrieval: Keys are retrieved live with every SSH connection
- Key Deactivation: Immediate blocking of SSH keys possible
- Audit Trail: Tracking of all key accesses
- Password Hashing: Secure password storage with Symfony's Password Hasher
- Input Validation: Comprehensive validation of all inputs
- SQL Injection Protection: Doctrine ORM with prepared statements
- CSRF Protection: Built-in CSRF protection for forms
- Server Health Monitoring: Automatic monitoring of server connections
- SSH Key Usage Tracking: Tracking of key usage
- Last Seen Timestamps: Monitoring of server activity
- User Activities: Logging of all user actions
- Key Access: Logging of all SSH key retrievals
- System Events: Monitoring of system events
# .env.local
APP_ENV=prod
APP_SECRET=your-production-secret
DATABASE_URL=mysql://user:password@host:port/shellock
# Production optimizations
composer dump-autoload --optimize --no-dev
npm run build
php bin/console cache:clear --env=prod
php bin/console cache:warmup --env=prodFor production, a reverse proxy (nginx/Apache) with SSL termination should be used:
server {
listen 443 ssl;
server_name shellock.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/private.key;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Code Style: PSR-12 for PHP, ESLint for JavaScript
- Testing: All new features must be covered with tests
- Documentation: Important changes must be documented
- Security: Security-related changes must be especially reviewed
This project is under the MIT License.
SSH keys are not being retrieved:
- Check server registration and API connection
- Test API connection:
curl http://localhost:8000/api/ssh-keys/{serverId}/{username} - Check SSH configuration:
sshd -t - Verify server registration code and status
Application won't start:
- Check PHP version:
php --version(requires PHP 8.4+) - Check port conflicts:
netstat -tulpn | grep :8000 - Check disk space:
df -h - Verify database connection in
.env.local
Database connection failed:
- Check MySQL/MariaDB status:
systemctl status mysql - Check credentials in
.env.local - Test database connection:
php bin/console doctrine:database:create - Run migrations:
php bin/console doctrine:migrations:migrate
# Debug logs
tail -f var/log/dev.log
# Symfony profiler (in dev mode)
# Available at /_profiler when APP_ENV=dev
# Database access
mysql -u your_user -p shellock
# Clear cache
php bin/console cache:clear
# Check routes
php bin/console debug:routerFor questions or issues, please create a GitHub Issue or contact the development team.
Shellock - Secure, centralized SSH access management for modern IT infrastructures.