Split alknet-core configuration into StaticConfig (immutable after startup)
and DynamicConfig (hot-reloadable at runtime via ArcSwap).
- Add StaticConfig struct in config/static_config.rs with all fields per ADR-030
- Add DynamicConfig struct with AuthPolicy, ForwardingPolicy, RateLimitConfig
- Add ForwardingPolicy with allow_all()/deny_all() defaults (ADR-031)
- Add ConfigReloadHandle with reload() method for runtime config updates
- Replace Arc<ServerAuthConfig> with Arc<ArcSwap<DynamicConfig>> in ServerHandler
- Add config_reload_handle() to Server for obtaining reload handles
- Add AuthPolicy with authenticate_publickey/authenticate_certificate methods
- All existing tests pass with the new config structure
- Default DynamicConfig produces identical behavior to current code
Enable running wraith alongside iroh-blobs, iroh-gossip, and iroh-docs
on the same QUIC endpoint (one connection per peer, multiplexed by ALPN).
- IrohTransport::from_endpoint(node_id, endpoint) for client-side shared endpoint
- IrohAcceptor::from_endpoint(endpoint) for server-side shared endpoint
- Export ALPN constant as IROH_ALPN for Router registration
- Add owned() method to track whether the endpoint was created internally
- Existing new()/bind() constructors unchanged (backwards compatible)
- Add tests for from_endpoint constructors and shared endpoint connectivity
- Restrict auth methods to PUBLICKEY only (no none, password, hostbased,
or keyboard-interactive advertised during negotiation)
- Log all denied channel types (session, x11, forwarded-tcpip) and
dangerous request types (exec, shell, subsystem, pty, env, x11, agent)
- Explicitly reject all dangerous channel request handlers (exec, shell,
subsystem, pty, env, x11, agent forwarding) with channel_failure
responses instead of russh's default silent Ok(()) which leaves clients
hanging and is a footgun if session channels are ever allowed
- Explicitly reject tcpip_forward, streamlocal_forward with logged warnings
- Log signal requests at debug level (harmless, no response needed)
- Override handlers in both core ServerHandler and NapiServerHandler
- Add tracing dependency to wraith-napi for security event logging
- Set preferred algorithms explicitly (russh::Preferred::DEFAULT which
uses only modern KEX/cipher/MAC algorithms)
Add top-level README.md with alpha status warning, quick start guide,
architecture overview, feature flags, transport modes, auth docs, and
Node.js API examples.
Add dual LICENSE-MIT and LICENSE-APACHE files.
Add comprehensive crate-level and module-level rustdoc to all three
crates (wraith-core, wraith, wraith-napi) and all public modules
(transport, client, server, auth, socks5, error). Add doc comments to
key public types (Transport, TransportAcceptor, ConnectOptions,
ClientSession, Server, ServeOptions, KeySource, ServerAuthConfig, etc).
Update Cargo.toml files with workspace-level package metadata
(version, edition, license, repository) and crate descriptions.
- handler.channel_open_direct_tcpip now proxies non-wraith channels via
connect_outbound+proxy_channel instead of dropping them
- ClientSession.run() spawns reconnect monitor that detects handle closure,
reconnects with exponential backoff (1s/2s/4s/8s/16s/30s cap),
and re-registers remote port forwards
- Remove server-side logging of tunnel destinations (ADR-006 compliance)
- Remove debug-level logging of proxy targets in channel_proxy
Expose NAPI serve() per ADR-016. WraithServer provides close() and
onConnection(callback) for receiving SSH channel streams from
incoming connections. Each connection produces a WraithServerStream
(Duplex-like read/write/close) with ConnectionInfo (remoteAddr,
transportKind). Supports TCP transport with optional authorizedKeys
and certAuthority auth. TLS and iroh transports return helpful errors
indicating future support.
Add stealth mode detection that peeks at the first bytes after TLS handshake
to determine SSH vs HTTP protocol. SSH connections proceed to russh handler;
non-SSH connections receive a fake nginx 404 response, making the server
indistinguishable from an ordinary HTTPS site to scanners and DPI systems.
- ProtocolDetection enum (Ssh, Http) for protocol classification
- detect_protocol() uses BufReader::fill_buf() to peek without consuming bytes
- send_fake_nginx_404() writes HTTP/1.1 404 + Server: nginx headers
- validate_stealth_config() enforces TLS transport requirement for stealth
- 17 unit tests covering SSH banner, HTTP, random data, and edge cases
- Add WraithConnectOptions struct with napi fields: server, peer, transport,
identity (string path or Buffer), tlsServerName, insecure, irohRelay, proxy
- Add WraithStream napi class wrapping SSH channel read/write halves via
ChannelStream::into_stream() + tokio::io::split()
- Implement connect() async function: transport creation (tcp, tls), SSH client
connection, authenticate, open direct_tcpip channel, return WraithStream
- Identity field accepts file path (string) or in-memory key data (Buffer)
- All Rust errors marshalled to JavaScript exceptions with descriptive messages
- Add ForwardError enum to wraith-core (required by forward.rs)
- Enable tls, iroh features on wraith-core dependency
- 7 unit tests for key source resolution and address parsing
Adds client/connect.rs with ConnectOptions (programmatic API per ADR-011),
ClientSession::new() for SSH session establishment, ClientSession::run()
for SOCKS5 + port forwards + shutdown, and graceful shutdown via
SIGTERM/SIGINT with SSH disconnect and 2s drain timeout.
Add ConnectionRateLimiter (HashMap<IpAddr, usize>) and AuthAttemptLimiter
with check/on_connect/on_disconnect and check/on_failure methods.
Integrate into ServerHandler with structured tracing::info! logging for
auth attempts, connection opened/closed events. No logging of tunnel
destinations per ADR-006. Also add ForwardError type and fix type
annotation in forward.rs to unblock compilation.
Add AcmeCertProvider with domain-based and IP-based modes using rustls-acme.
AcmeTlsAcceptor::bind_acme() and TlsAcceptor::bind_acme() provide ACME-integrated
TLS acceptance with automatic cert renewal via background tokio task.
Feature-gated behind 'acme' (implies 'tls'). Unit tests for config construction;
integration test for LE staging marked #[ignore].
Convert socks5.rs to directory module with protocol parsing and server
implementation. Socks5Server binds to configurable address (default
127.0.0.1:1080), handles SOCKS5 handshake (no-auth), parses IPv4/IPv6/domain
addresses, and proxies bidirectionally via SSH direct_tcpip channels.
Domain names sent unresolved (SOCKS5h) to prevent DNS leaks (ADR-006).
No logging of request targets per privacy requirements.
Add iroh QUIC P2P transport using tokio::io::join for stream duplexing
per ADR-003. Default relay is n0's https://relay.iroh.network/ (ADR-009).
Proxy URL passed to Endpoint::builder (ADR-010). Integration test marked
#[ignore] for CI since it requires iroh relay connectivity.