내가 사용하는 격리된 네트워크에 도달하려면SSH -D
양말 대리인.
추가할 때마다 세부정보를 입력하지 않으려면 다음 단계를 따르세요 ~/.ssh/config
.
$ awk '/Host socks-proxy/' RS= ~/.ssh/config
Host socks-proxy
Hostname pcit
BatchMode yes
RequestTTY no
Compression yes
DynamicForward localhost:9118
그런 다음 나는시스템 사용자서비스 단위 정의 파일:
$ cat ~/.config/systemd/user/SocksProxy.service
[Unit]
Description=SocksProxy Over Bridge Host
[Service]
ExecStart=/usr/bin/ssh -Nk socks-proxy
[Install]
WantedBy=default.target
데몬이 새 서비스 정의를 다시 로드하고, 새 서비스를 활성화하고, 시작하고, 상태를 확인하고 수신 중인지 확인하도록 합니다.
$ systemctl --user daemon-reload
$ systemctl --user list-unit-files | grep SocksP
SocksProxy.service disabled
$ systemctl --user enable SocksProxy.service
Created symlink from ~/.config/systemd/user/default.target.wants/SocksProxy.service to ~/.config/systemd/user/SocksProxy.service.
$ systemctl --user start SocksProxy.service
$ systemctl --user status SocksProxy.service
● SocksProxy.service - SocksProxy Over Bridge Host
Loaded: loaded (/home/alex/.config/systemd/user/SocksProxy.service; enabled)
Active: active (running) since Thu 2017-08-03 10:45:29 CEST; 2s ago
Main PID: 26490 (ssh)
CGroup: /user.slice/user-1000.slice/[email protected]/SocksProxy.service
└─26490 /usr/bin/ssh -Nk socks-proxy
$ netstat -tnlp | grep 118
tcp 0 0 127.0.0.1:9118 0.0.0.0:* LISTEN
tcp6 0 0 ::1:9118 :::* LISTEN
이것은 예상대로 작동합니다. 그런 다음 서비스를 수동으로 시작하거나 영구적으로 실행하는 것을 방지하고 싶습니다.자동 SSH, 사용하여체계 소켓 활성화주문형 (재생)생성에 사용됩니다. 작동하지 않는 것 같습니다. (내 버전) ssh
이 소켓 파일 설명자를 받을 수 없는 것 같습니다.
문서를 찾았습니다 (1,2), 그리고한 가지 예사용하기위한systemd-socket-proxyd
- 서비스를 "래핑"하는 두 가지 도구인 "서비스"와 "소켓"을 만듭니다.
$ cat ~/.config/systemd/user/SocksProxyHelper.socket
[Unit]
Description=On Demand Socks proxy into Work
[Socket]
ListenStream=8118
#BindToDevice=lo
#Accept=yes
[Install]
WantedBy=sockets.target
$ cat ~/.config/systemd/user/SocksProxyHelper.service
[Unit]
Description=On demand Work Socks tunnel
After=network.target SocksProxyHelper.socket
Requires=SocksProxyHelper.socket SocksProxy.service
After=SocksProxy.service
[Service]
#Type=simple
#Accept=false
ExecStart=/lib/systemd/systemd-socket-proxyd 127.0.0.1:9118
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target
$ systemctl --user daemon-reload
이것~인 것 같다ssh
죽거나 죽임을 당할 때까지 일하십시오 . 그러면 다음 연결 시도 시 다시 생성되지 않습니다.
질문:
- /usr/bin/ssh가 systemd가 전달한 소켓을 허용할 수 없다는 것이 사실입니까? 아니면 최신 버전인가요? 내 것은최신 데비안 8.9 중 하나.
- 이 옵션은 루트 유닛에서만 사용할 수 있습니까
BindTodevice
? - 이전 터널이 만료된 후 첫 번째 새 연결에서 프록시 서비스가 올바르게 다시 생성되지 않는 이유는 무엇입니까?
- 이것이 "요청 시 SSH 프록시"를 설정하는 올바른 방법입니까? 그렇지 않다면 어떻게 합니까?
답변1
- /usr/bin/ssh가 systemd가 전달한 소켓을 허용할 수 없다는 것이 사실입니까?
다음 사항을 고려하면 이는 별로 놀라운 일이 아닌 것 같습니다.
- OpenSSH는 OpenBSD 프로젝트입니다
- systemd는 Linux 커널만 지원합니다.
- systemd 지원은 선택 사항/빌드 타임 종속성으로 OpenSSH에 명시적으로 추가해야 하므로 판매가 어려울 수 있습니다.
- 이 옵션은 루트 유닛에서만 사용할 수 있습니까
BindTodevice
?
사용자 systemd 인스턴스는 마스터 pid-0 인스턴스와 통신할 수 없는 등 매우 격리된 경우가 많습니다. 사용자 단위 파일의 시스템 단위에 의존하는 것과 같은 것은 불가능합니다.
언급된 문서 BindToDevice
:
이 매개변수를 설정하면 장치에 추가 종속성이 추가될 수 있습니다(위 참조).
위의 제한으로 인해 이 옵션은 사용자 시스템 인스턴스에 영향을 미치지 않는다는 것을 암시할 수 있습니다.
- 이전 터널이 만료된 후 첫 번째 새 연결에서 프록시 서비스가 올바르게 다시 생성되지 않는 이유는 무엇입니까?
내가 아는 한 일련의 사건은 다음과 같습니다.
SocksProxyHelper.socket
시작되었습니다.- SOCKS 클라이언트는 localhost:8118에 연결됩니다.
- 시스템이 시작됩니다
SocksProxyHelper.service
. - 종속성으로
SocksProxyHelper.service
systemd도 시작됩니다SocksProxy.service
. systemd-socket-proxyd
시스템 소켓을 수락하고 해당 데이터를ssh
.ssh
죽거나 죽임을 당합니다.- systemd는 이를 인지하고 비활성 상태로 설정
SocksProxy.service
하지만 아무 작업도 수행하지 않습니다. SocksProxyHelper.service
ssh
계속 실행되고 연결을 수락하지만 더 이상 실행되지 않기 때문에 연결할 수 없습니다 .
수정 사항은 해당 설명서를 인용하여 추가하는 것입니다 BindsTo=SocksProxy.service
( SocksProxyHelper.service
강조 추가).
구성에는 로 스타일 지정된 종속성이 필요합니다 . 그러나 이 종속성 유형은 선언된 효과
Requires=
외에도 더 강력합니다 .Requires=
바인딩된 유닛이 정지되면 본 유닛도 정지됩니다.. 즉, 갑자기 비활성화된 다른 장치에 바인딩된 장치도 중지됩니다. 여러 가지 이유로 장치가 갑자기 예기치 않게 비활성화될 수 있습니다.서비스 단위의 주요 프로세스가 자체적으로 종료될 수 있습니다., 장치 장치의 지원 장치가 분리되거나 장치가 설치된 장착 지점이 시스템 및 서비스 관리자의 개입 없이 분리될 수 있습니다.동일한 장치에 결합하면
After=
동작이BindsTo=
더욱 강력해집니다. 이 경우 해당 유닛은 다음과 같이 바인딩됩니다.장치도 활성화하려면 엄격하게 활성화되어야 합니다.. 이는 다른 유닛에 바인딩된 유닛이 갑자기 비활성화된다는 의미일 뿐만 아니라, 다른 유닛에 바인딩된 유닛이 조건 확인 실패로 인해 건너뛴다는 의미이기도 합니다(예:ConditionPathExists=
,,,ConditionPathIsSymbolicLink=
... - 아래 참조). 달리기. 따라서 많은 경우에BindsTo=
와 함께 사용하는 것이 가장 좋습니다After=
.
- 이것이 "요청 시 SSH 프록시"를 설정하는 올바른 방법입니까? 그렇지 않다면 어떻게 합니까?
"올바른 방법"이 없을 수도 있습니다. 이 접근 방식에는 장점(모든 것이 "주문형"임)과 단점(systemd에 의존, ssh가 아직 수신을 시작하지 않았기 때문에 첫 번째 연결이 진행되지 않음)이 있습니다. 아마도 autossh에서 systemd 소켓 활성화 지원을 구현하는 것이 더 나은 솔루션이 될 것입니다.
답변2
나중에 참조할 수 있도록 systemd --user
아래 데몬을 사용하여 주문형 SSH 터널에 대한 구성 파일을 systemd-socket-proxyd
다양한 개선 사항 및 설명 설명과 함께 붙여넣었습니다.
~/.config/systemd/user/ssh-tunnel-proxy.socket
[Unit]
Description=Socket-activation for SSH-tunnel
[Socket]
ListenStream=1000
[Install]
WantedBy=sockets.target
~/.config/systemd/user/ssh-tunnel-proxy.service
[Unit]
Description=Socket-activation proxy for SSH tunnel
## Stop also when stopped listening for socket-activation.
BindsTo=ssh-tunnel-proxy.socket
After=ssh-tunnel-proxy.socket
## Stop also when ssh-tunnel stops/breaks
# (otherwise, could not restart).
BindsTo=ssh-tunnel.service
After=ssh-tunnel.service
[Service]
ExecStart=/lib/systemd/systemd-socket-proxyd --exit-idle-time=500s localhost:1001
~/.config/systemd/user/ssh-tunnel.service
[Unit]
Description=Tunnel to SSH server
## Stop-when-idle is controlled by `--exit-idle-time=` in proxy.service
# (from `man systemd-socket-proxyd`)
StopWhenUnneeded=true
[Service]
Type=simple
## Prefixed with `-` not to mark service as failed on net-fails;
# will be restarted on-demand by socket-activation.
ExecStart=-/usr/bin/ssh -kaxNT -o ExitOnForwardFailure=yes hostname_in_ssh_config -L 1001:localhost:2000
## Delay enough time to allow for ssh-authentication to complete
# so tunnel has been established before proxy process attaches to it,
# or else the first SYN request will be lost.
ExecStartPost=/bin/sleep 2
맞춤 제작
위 스크립트에서 다음 문자열을 바꿔야 합니다.
1000
- (ssh-tunnel-proxy.socket
문서)
뭐(호스트:)포트로컬 MYSql 포트 에뮬레이션과 같은 로컬 청취 터널을 위한 소켓 활성화.1001
- (ssh-tunnel-proxy.service
및ssh-tunnel.service
파일)
로컬이란 무엇입니까?(호스트:)포트에이전트가 SSH 서비스 프로세스로 전달할 때 사용됩니다.
사용되지 않는 포트를 선택하세요.hostname_in_ssh_config
- (ssh-tunnel.service
파일)
연결할 호스트 그룹입니다.SSH 구성 (모든 SOCKS 구성이 여기에 속합니다).localhost:2000
- (ssh-tunnel.service
파일)
SSH 터널 원격호스트:포트원격 MYSql이 바인딩되는 위치와 같은 끝점입니다.- x2 지연 시간(
ssh-tunnel-proxy.service
및ssh-tunnel.service
문서)
주석에 설명되어 있습니다. ssh-tunnel-...
- (모든 유닛 파일의 접두사)
터널링에 대한 필요성을 설명합니다mysql-tunnel-...
. 예: .- SSH- (
Description=
모든 유닛 파일의 지시문에서)
터널링에 대한 요구 사항을 설명합니다MYSql
. 예: .
터널을 제어하는 명령
# After any edits.
systemctl --user daemon-reload
# If socket's unit-file has been edited.
systemctl --user restart ssh-tunnel-proxy.socket
# To start listening for on-demand activation of the tunnel
systemctl --user start ssh-tunnel.socket
# To enable on-demand tunnel on Boot
systemctl --user enable ssh-tunnel-proxy.socket
# To gracefully stop tunnel (any cmd will do)
systemctl --user stop ssh-tunnel.service
systemctl --user stop ssh-tunnel-proxy.service
# To gracefully stop & disable tunnel (till next reboot)
systemctl --user stop ssh-tunnel-proxy.socket
# To view the health of the tunnel
systemctl --user status ssh-tunnel-proxy.{socket,service} ssh-tunnel
# To reset tunnel after errors (both cmds may be needed)
systemctl --user reset-failed ssh-tunnel ssh-tunnel-proxy
systemctl --user restart ssh-tunnel-proxy.socket
답변3
평판 시스템 때문에 @ankostis 솔루션에 대해서는 언급할 수 없습니다...
systemd에 bash 수면 루프 사용을 피할 수 있는 옵션이 있는 것 같습니다.
예, systemd-notify가 있습니다.
또한 다음과 같이 로컬 포트 낭비를 피하기 위해 systemd-socket-proxyd와 ssh 사이에 소켓을 사용하라는 @noam의 제안과 함께:
~/.config/systemd/user/ssh-tunnel-proxy.service
[Unit]
Description=Socket-activation proxy for SSH tunnel
## Stop also when stopped listening for socket-activation.
BindsTo=ssh-tunnel-proxy.socket
After=ssh-tunnel-proxy.socket
## Stop also when ssh-tunnel stops/breaks
# (otherwise, could not restart).
BindsTo=ssh-tunnel.service
After=ssh-tunnel.service
[Service]
ExecStart=/lib/systemd/systemd-socket-proxyd --exit-idle-time=500s ${XDG_RUNTIME_DIR}/ssh-tunnel-proxy
~/.config/systemd/user/ssh-tunnel.service
[Unit]
Description=Tunnel to SSH server
## Stop-when-idle is controlled by `--exit-idle-time=` in proxy.service
# (from `man systemd-socket-proxyd`)
StopWhenUnneeded=true
[Service]
Type=notify
NotifyAccess=all
## Prefixed with `-` not to mark service as failed on net-fails;
# will be restarted on-demand by socket-activation.
ExecStart=-/usr/bin/ssh -kaxNT -o ExitOnForwardFailure=yes -o ControlMaster=no -o StreamLocalBindUnlink=yes -o PermitLocalCommand=yes -o LocalCommand="systemd-notify --ready" hostname_in_ssh_config -L ${XDG_RUNTIME_DIR}/ssh-tunnel-proxy:localhost:2000
ssh_config 매뉴얼 페이지에서는 LocalCommand "서버에 성공적으로 연결한 후 로컬 컴퓨터에서 실행할 명령 지정"에 대해 설명합니다.
ControlMaster=no
멀티플렉싱을 사용할 때 SSH 세션이 마스터되지 않도록 하십시오. 동일한 호스트에 대한 다른 모든 멀티플렉싱된 SSH 세션이 자동으로 닫히고 종료되기 때문입니다.
마지막으로 소켓 포트를 localhost에 바인딩하는 것이 좋습니다.
~/.config/systemd/user/ssh-tunnel-proxy.socket
[Unit]
Description=Socket-activation for SSH-tunnel
[Socket]
ListenStream=127.0.0.1:1000
ListenStream=[::1]:1000
[Install]
WantedBy=sockets.target
답변4
아직 이것을 테스트하고 있지만(이 답변을 작성할 때 사용하고 있습니다) 누락된 성분이 바이너리 -o ExitOnForwardFailure=yes
에 옵션으로 포함되어 있다고 생각합니다 ssh
.