Last active
August 28, 2024 09:41
-
-
Save win-t/c08556fc7091937981c71287eb9ee658 to your computer and use it in GitHub Desktop.
golang: unix socket: get peer credential
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"net" | |
"os" | |
) | |
func main() { | |
addr, _ := net.ResolveUnixAddr("unix", "@testabstractsocket") | |
client, err := net.DialUnix("unix", nil, addr) | |
if err != nil { | |
fmt.Println("Cannot dial", err.Error()) | |
os.Exit(1) | |
} | |
defer client.Close() | |
fmt.Println("Connected!") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"net" | |
"os" | |
"syscall" | |
) | |
func main() { | |
addr, _ := net.ResolveUnixAddr("unix", "@testabstractsocket") | |
server, err := net.ListenUnix("unix", addr) | |
if err != nil { | |
fmt.Println("Cannot listen", err.Error()) | |
os.Exit(1) | |
} | |
for { | |
client, err := server.AcceptUnix() | |
if err != nil { | |
fmt.Println("Cannot accept", err.Error()) | |
continue | |
} | |
go serve(client) | |
} | |
} | |
func serve(client *net.UnixConn) { | |
defer client.Close() | |
f, err := client.File() | |
if err != nil { | |
fmt.Println("Cannot get underlying file", err.Error()) | |
return | |
} | |
defer f.Close() | |
cred, err := syscall.GetsockoptUcred(int(f.Fd()), syscall.SOL_SOCKET, syscall.SO_PEERCRED) | |
if err != nil { | |
fmt.Println("Cannot get peer credential", err.Error()) | |
return | |
} | |
if cred.Uid == 0 { | |
fmt.Println("root client connected, do something dangerous !") | |
} else { | |
fmt.Println("non-root client connected, do nothing !") | |
} | |
} |
It doesn't affect unix socket that listens on filesystems, because filesystems is protected by mount namespace
Thanks for this! Totally adjacent but a really handy example on how to do socket auth!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
this gist is about a demonstration to show that it is not secure to use
--net host
on docker. Because some unix socket server implementation that listen on abstract address, may do client authentication based on peer UID.build the server
go build -o server server.go
build the client
go build -o client client.go
run the server
./server
run the client
./client
run the client on docker
docker run -it --rm -v $PWD:/shared --net host ubuntu bash -c "/shared/client"
when using
--net host
, container will use network namespace from host system, which also mean exposing host system abstract socket address.From my machine running
ss -xlpn | grep @
inside the container printthere are bunch of abstract unix socket that can be connected from inside container as root