mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 22:37:28 +00:00
tor: premium tor-url / tor-irc / tor routes over Tor
Add three premium-gated SSH routes:
ssh tor-url@host <url> one-shot HTTP(S) GET over Tor (host-side,
curl via SOCKS, 30s/2MB caps, http/https only)
ssh -t tor-irc@host <server> interactive IRC over Tor in the member's pod
ssh -t tor@host <command...> run any command over Tor (torsocks) in the pod
tor-url runs host-side and constrained; tor/tor-irc run inside the member's
isolated pod (new pods.Exec) so arbitrary/interactive commands are sandboxed,
never on the host. internal/tor wraps curl/torsocks/irssi. All gated by
ensurePremium; names reserved. setup.sh installs + enables tor (SOCKS
127.0.0.1:9050) and torsocks.
Note: tor-url is host-side and self-contained. tor/tor-irc still need the pod
image to carry torsocks+irssi and reach the Tor SOCKS — follow-up.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ac4b0873d9
commit
4be87440d5
5 changed files with 285 additions and 1 deletions
|
|
@ -144,6 +144,47 @@ func (m *Manager) Attach(s ssh.Session, user string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Exec provisions the user's pod and runs argv inside it wired to the SSH
|
||||
// session (PTY required). Used for tor@/tor-irc@ so arbitrary or interactive
|
||||
// commands run sandboxed in the member's container, never on the host. Blocks
|
||||
// until the command exits or the session closes.
|
||||
func (m *Manager) Exec(s ssh.Session, user string, argv []string) error {
|
||||
if len(argv) == 0 {
|
||||
return fmt.Errorf("pods: no command given")
|
||||
}
|
||||
ptyReq, winCh, hasPty := s.Pty()
|
||||
if !hasPty {
|
||||
return fmt.Errorf("pods: a PTY is required (ssh -t)")
|
||||
}
|
||||
name, err := m.ensure(user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
args := append([]string{"exec", "-it", "-e", "TERM=" + ptyReq.Term, name}, argv...)
|
||||
cmd := exec.Command(m.engine, args...)
|
||||
f, err := pty.Start(cmd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pods: exec failed: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
m.ref(name, +1)
|
||||
defer m.deref(name)
|
||||
|
||||
_ = pty.Setsize(f, &pty.Winsize{Rows: uint16(ptyReq.Window.Height), Cols: uint16(ptyReq.Window.Width)})
|
||||
go func() {
|
||||
for w := range winCh {
|
||||
_ = pty.Setsize(f, &pty.Winsize{Rows: uint16(w.Height), Cols: uint16(w.Width)})
|
||||
}
|
||||
}()
|
||||
|
||||
go func() { _, _ = io.Copy(f, s) }() // ssh -> pod
|
||||
_, _ = io.Copy(s, f) // pod -> ssh
|
||||
_ = cmd.Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) ref(name string, d int) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue