运行 main.go, 文件写到本地。 本身的 sshd 服务监听地址从 22 端口改到其他端口。
package main
import (
"bufio"
"encoding/json"
"errors"
"flag"
"fmt"
"golang.org/x/crypto/ssh"
"log"
"net"
"os"
"path/filepath"
)
// ssh-keygen -t rsa -f ~/.ssh/id_rsa_fake
const pk = `-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----`
var (
saveFile string
)
func init() {
flag.StringVar(&saveFile, "f", "file.txt", "filepath")
}
type Source struct {
IP string `json:"ip"`
Username string `json:"username"`
Password string `json:"password"`
}
func (s *Source) String() string {
b, _ := json.Marshal(s)
return string(b)
}
func main() {
flag.Parse()
dir := filepath.Dir(saveFile)
os.MkdirAll(dir, 0755)
fi, err := os.OpenFile(saveFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
if err != nil {
fmt.Println("openfile failed: ", err)
return
}
defer fi.Close()
buf := bufio.NewWriter(fi)
defer buf.Flush()
// 创建 SSH 服务器配置
config := &ssh.ServerConfig{
NoClientAuth: false, // 启用客户端认证
}
// 生成 SSH 密钥对
privateKey, err := ssh.ParsePrivateKey([]byte(pk))
if err != nil {
log.Fatalf("Failed to parse private key: %v", err)
}
config.AddHostKey(privateKey)
// 添加用户身份验证
config.PasswordCallback = func(ctx ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
s := Source{
IP: ctx.RemoteAddr().String(),
Username: ctx.User(),
Password: string(password),
}
fmt.Fprintln(buf, s.String())
buf.Flush()
fmt.Println(s.String())
return nil, errors.New("invalid password")
}
// 监听 22 端口
listener, err := net.Listen("tcp", ":22")
if err != nil {
log.Fatalf("Failed to listen on 22: %v", err)
}
log.Println("Listening on :22 ...")
for {
// 接受连接
conn, err := listener.Accept()
if err != nil {
log.Fatalf("Failed to accept connection: %v", err)
}
// 处理连接
go handleConnection(conn, config)
}
}
func handleConnection(conn net.Conn, config *ssh.ServerConfig) {
defer conn.Close()
// 进行 SSH 握手
ssh.NewServerConn(conn, config)
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.