Documentation
¶
Overview ¶
Package ironport provides an embeddable, security-hardened SFTP and FTP server.
Core features:
- Per-user jail roots enforced via path resolution and symlink checks.
- Password and SSH public-key authentication with constant-time comparisons.
- Fine-grained CanRead / CanWrite per-user permission flags.
- Runtime user management (AddUser, RemoveUser, RemoveAllUsers, AddUserKey, RemoveUserKey).
- Optional SSH algorithm pinning for key exchange, ciphers, MACs, and public-key auth signatures.
- Graceful shutdown via Close; upload-completion notifications via CompletedUploads; authentication/session notifications via AuthEvents.
- Optional FTP listener sharing the same users, jails, permissions, temp-extension handling, CompletedUploads stream, and AuthEvents stream as SFTP. FTP uses passive mode by default; active mode can be enabled explicitly.
- Optional FTPS (RFC 4217 explicit TLS via AUTH TLS) over the FTP listener. Set Config.FtpTLSConfig to enable it and Config.FtpRequireTLS to refuse plaintext logins.
Typical usage:
cfg := ironport.DefaultConfig() cfg.SftpAddr = ":2022" cfg.FtpAddr = ":2121" cfg.Users = users cfg.SftpSigner = signer srv := ironport.NewServer(cfg) log.Fatal(srv.ListenAndServe())
Index ¶
- Constants
- func NewSignerFromFile(path string) (ssh.Signer, error)
- type AuthEvent
- type AuthEventType
- type CompletedUpload
- type Config
- type Server
- func (s *Server) AddUser(username string, info UserInfo)
- func (s *Server) AddUserKey(username string, key ssh.PublicKey)
- func (s *Server) AuthEvents() <-chan AuthEvent
- func (s *Server) Close() error
- func (s *Server) CompletedUploads() <-chan CompletedUpload
- func (s *Server) FTPListeningAddr() net.Addr
- func (s *Server) ListenAndServe() error
- func (s *Server) ListeningAddr() net.Addr
- func (s *Server) RemoveAllUsers()
- func (s *Server) RemoveUser(username string)
- func (s *Server) RemoveUserKey(username string, key ssh.PublicKey)
- func (s *Server) Shutdown(ctx context.Context) error
- type UserInfo
Constants ¶
const ( // CompletedUploadProtocolSFTP identifies an upload completed through SFTP. CompletedUploadProtocolSFTP = "SFTP" // CompletedUploadProtocolFTP identifies an upload completed through FTP. CompletedUploadProtocolFTP = "FTP" )
Variables ¶
This section is empty.
Functions ¶
func NewSignerFromFile ¶
NewSignerFromFile reads a PEM-encoded private key from the given file path and returns an ssh.Signer suitable for use as a server host key. It supports any key type accepted by ssh.ParsePrivateKey (RSA, ECDSA, Ed25519).
Types ¶
type AuthEvent ¶ added in v0.1.7
type AuthEvent struct {
// Type is the authentication event kind.
Type AuthEventType
// Username is the username supplied by the client for this event.
Username string
// ClientIP is the remote IP address of the client, without the port. It is
// empty if the address could not be parsed.
ClientIP string
// Protocol is the file-transfer protocol used for the event.
// It is either CompletedUploadProtocolSFTP or CompletedUploadProtocolFTP.
Protocol string
}
AuthEvent describes an authentication or session-lifecycle event. It is the payload delivered on the server's AuthEvents stream.
type AuthEventType ¶ added in v0.1.7
type AuthEventType string
AuthEventType identifies the kind of authentication event delivered on the AuthEvents channel (login success, login failure, or logout).
const ( // AuthEventLoginSuccess identifies a successful user login. AuthEventLoginSuccess AuthEventType = "LoginSuccess" // AuthEventLoginFailed identifies a rejected user login attempt. AuthEventLoginFailed AuthEventType = "LoginFailed" // AuthEventLogout identifies the end of an authenticated session. AuthEventLogout AuthEventType = "Logout" )
type CompletedUpload ¶
type CompletedUpload struct {
// Username is the authenticated SFTP/FTP user that performed the upload.
Username string
// FullFilePath is the absolute path of the uploaded file on the server's
// local filesystem (i.e. resolved through the user's jail root).
FullFilePath string
// FilePath is the file path as seen by the client, relative to the
// user's jail root (e.g. "/incoming/foo.txt").
FilePath string
// ClientIP is the remote IP address of the client that performed
// the upload, without the port. It is empty if the address could not
// be parsed.
ClientIP string
// Protocol is the file-transfer protocol used for the upload.
// It is either CompletedUploadProtocolSFTP or CompletedUploadProtocolFTP.
Protocol string
}
CompletedUpload describes a file upload that has finished successfully. It is the payload delivered on the server's CompletedUploads stream.
type Config ¶ added in v0.1.17
type Config struct {
SftpAddr string
FtpAddr string
FtpPassivePortRange string
// FtpDataAcceptTimeout bounds how long passive-mode FTP data listeners wait
// for the client data connection after PASV/EPSV, and how long active-mode
// FTP dials may take after PORT/EPRT. Zero selects the package default
// (30 seconds); negative disables the deadline.
FtpDataAcceptTimeout time.Duration
// FtpAllowActiveMode enables FTP active mode (PORT/EPRT). It defaults to
// false because active mode requires outbound connections from the server.
// When enabled, this server only dials the same IP as the control connection.
FtpAllowActiveMode bool
// FtpTLSConfig, when non-nil, enables explicit FTPS (RFC 4217). The
// AUTH TLS command upgrades the control connection using this config,
// and PROT P wraps the data connection. A separate config is derived
// internally for data connections to require session resumption from
// the control channel; callers should populate Certificates (or a
// GetCertificate callback) but otherwise leave session-ticket settings
// at their defaults. Leave nil to disable FTPS.
FtpTLSConfig *tls.Config
// FtpRequireTLS, when true, refuses USER/PASS over the FTP control
// connection until AUTH TLS has succeeded. Requires FtpTLSConfig to be
// set; otherwise the FTP listener would have no path to authentication
// and every login attempt would be rejected.
FtpRequireTLS bool
Users map[string]UserInfo
SftpSigner ssh.Signer
CompletedUploadSize int
AuthEventSize int
// SSHKeyExchanges, SSHCiphers, SSHMACs, and
// SSHPublicKeyAuthAlgorithms optionally pin SSH negotiation and public-key
// auth signature algorithms. Nil slices use golang.org/x/crypto/ssh
// defaults.
SSHKeyExchanges []string
SSHCiphers []string
SSHMACs []string
SSHPublicKeyAuthAlgorithms []string
// TempExtensions marks file extensions that should defer completion
// notifications until a later rename to a non-temp name. Matching is
// case-insensitive.
TempExtensions []string
// IdleTimeout bounds authenticated SFTP connection inactivity and FTP
// control-session inactivity between commands. Zero selects the package
// default; negative disables the idle timeout.
IdleTimeout time.Duration
// TCPKeepAlivePeriod controls the SO_KEEPALIVE idle period applied to
// accepted SFTP and FTP control connections. Zero selects the package
// default (30 seconds); a negative value disables keepalive entirely.
// Probes keep idle control connections alive through stateful
// firewalls/NAT and surface half-open peers as read errors.
TCPKeepAlivePeriod time.Duration
// SftpAllowChown controls whether SFTP clients may change file ownership
// inside their jail. It defaults to false.
SftpAllowChown bool
}
Config holds the values used to construct a server.
func DefaultConfig ¶ added in v0.1.17
func DefaultConfig() *Config
DefaultConfig returns a fresh server configuration with package defaults applied. Callers should set Users before starting the server. Set SftpSigner to use a stable host key; when SftpSigner is nil, ListenAndServe generates an ephemeral in-memory host key.
type Server ¶ added in v0.1.18
type Server struct {
// contains filtered or unexported fields
}
Server is a self-contained SFTP server with optional FTP support.
func NewServer ¶
NewServer creates a new Server from config. Pass FtpAddr as "" to disable FTP. Leave FtpPassivePortRange empty to use OS-assigned passive data ports.
CompletedUploadSize sets the buffer capacity of the CompletedUploads channel. AuthEventSize sets the buffer capacity of the AuthEvents channel. A non-positive value falls back to the package default (64) for either stream:
cfg := ironport.DefaultConfig() cfg.Users = users cfg.SftpSigner = signer cfg.CompletedUploadSize = 256 cfg.AuthEventSize = 256 srv := ironport.NewServer(cfg)
func (*Server) AddUser ¶ added in v0.1.18
AddUser adds or replaces a user entry in the server's user map. It is safe to call concurrently with active connections.
func (*Server) AddUserKey ¶ added in v0.1.18
AddUserKey appends key to the AuthorizedKeys of an existing user. If the key is already present (by wire-format equality) it is not added again. It is a no-op when username does not exist or key is nil. It is safe to call concurrently with active connections.
func (*Server) AuthEvents ¶ added in v0.1.18
AuthEvents returns a receive-only stream of authentication/session notifications. Each AuthEvent includes the protocol that produced it. The channel is buffered; sends are non-blocking so a slow consumer never stalls authentication or logout handling. Callers should drain the stream continuously.
The buffer capacity is set by Config.AuthEventSize. A non-positive value falls back to the package default (64).
func (*Server) Close ¶ added in v0.1.18
Close stops both listeners, causing ListenAndServe to return nil. It is safe to call concurrently with active connections; in-flight connections are not terminated, and the server can be started again after Close returns. Calling Close before ListenAndServe has been called, or after it has already returned, is a no-op.
func (*Server) CompletedUploads ¶ added in v0.1.18
func (s *Server) CompletedUploads() <-chan CompletedUpload
CompletedUploads returns a receive-only stream of successful upload notifications. Each CompletedUpload includes the protocol that produced it. The channel is buffered; sends are non-blocking so a slow consumer never stalls an upload. Callers should drain the stream continuously.
The buffer capacity is set by Config.CompletedUploadSize. A non-positive value falls back to the package default (64).
func (*Server) FTPListeningAddr ¶ added in v0.1.18
FTPListeningAddr returns the actual FTP network address the server is listening on, or nil if FTP is disabled or not currently listening.
func (*Server) ListenAndServe ¶ added in v0.1.18
ListenAndServe starts the SFTP server and, when configured, the FTP server too. It blocks until Close or Shutdown is called or an unexpected listener error occurs. It returns nil when stopped via Close or Shutdown.
A stopped server can be started again by calling ListenAndServe after Close or Shutdown returns. Concurrent ListenAndServe calls are rejected.
func (*Server) ListeningAddr ¶ added in v0.1.18
ListeningAddr returns the actual SFTP network address the server is listening on, or nil if the SFTP listener is not currently listening. It is useful when the server was started with port 0 (OS-assigned port).
func (*Server) RemoveAllUsers ¶ added in v0.1.18
func (s *Server) RemoveAllUsers()
RemoveAllUsers removes every user entry from the server's user map and force-closes any connections currently authenticated as one of those users. Connections that have not yet completed authentication are left alone so they can either finish authenticating against the (now empty) user map or be rejected by it. No on-disk user data is removed. It is safe to call concurrently with active connections.
func (*Server) RemoveUser ¶ added in v0.1.18
RemoveUser removes a user entry from the server's user map and force-closes any connections currently authenticated as that user, so an in-flight session cannot keep operating after its credentials have been revoked. It is safe to call concurrently with active connections.
func (*Server) RemoveUserKey ¶ added in v0.1.18
RemoveUserKey removes key from the AuthorizedKeys of an existing user. It is a no-op when username does not exist, the key is not found, or key is nil. It is safe to call concurrently with active connections.
func (*Server) Shutdown ¶ added in v0.1.18
Shutdown gracefully stops the server. It closes the listeners so no new connections are accepted, then waits for every in-flight handler goroutine to return.
If ctx is canceled or its deadline passes before all handlers finish, Shutdown forcibly closes every remaining tracked connection (which causes each handler's network I/O to fail and the handler to return), waits for those handlers to exit, and returns ctx.Err(). Passing context.Background() blocks until all handlers exit.
Shutdown is safe to call concurrently with Close and with itself. After Shutdown returns, ListenAndServe (if it was running) will have returned nil, and the server can be started again. Calling Shutdown before ListenAndServe has been started, or after it has already returned and all handlers have exited, returns immediately with nil.
type UserInfo ¶
type UserInfo struct {
Password string
AuthorizedKeys []ssh.PublicKey // public keys allowed for SFTP authentication; nil or empty means public-key auth is disabled for this user
Root string // jail root on disk, e.g. /srv/sftp/alice
CanRead bool // allow read/download/list operations
CanWrite bool // allow write/upload/delete/rename operations
}
UserInfo holds the credentials and jail root for a single SFTP/FTP user.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
ironport-demo
command
Command ironport-demo is a runnable library demo for the ironport package.
|
Command ironport-demo is a runnable library demo for the ironport package. |