Skip to content

Instantly share code, notes, and snippets.

@djoreilly
Last active March 1, 2021 10:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save djoreilly/8c346ba8c047db65908d7a985cab812c to your computer and use it in GitHub Desktop.
Save djoreilly/8c346ba8c047db65908d7a985cab812c to your computer and use it in GitHub Desktop.
Allows Libvirt VMs with cloud-init to get users public ssh key
package main
import (
"flag"
"io"
"io/ioutil"
"log"
"net/http"
"os/user"
"path/filepath"
"strings"
)
func getPubSSHKey() ([]byte, error) {
usr, _ := user.Current()
path := filepath.Join(usr.HomeDir, ".ssh/id_rsa.pub")
key, err := ioutil.ReadFile(path)
if err != nil {
log.Println(err)
// return []byte{}, err
return nil, err
}
return key, nil
}
func handler(w http.ResponseWriter, req *http.Request) {
status := http.StatusOK
if req.RequestURI == "/" {
io.WriteString(w, "2016-09-02/")
} else {
// ignore "/YYYY-MM-DD/" start
switch req.RequestURI[12:] {
case "meta-data/":
io.WriteString(w, "instance-id\nhostname\npublic-keys/")
case "meta-data/instance-id":
ipAddr := strings.Split(req.RemoteAddr, ":")[0]
io.WriteString(w, "i-"+ipAddr)
case "meta-data/hostname":
// TODO maybe get hostname from libvirt
io.WriteString(w, "set-me")
case "meta-data/public-keys/":
io.WriteString(w, "0=default")
case "meta-data/public-keys/0/":
io.WriteString(w, "openssh-key")
case "meta-data/public-keys/0/openssh-key":
pubKey, err := getPubSSHKey()
if err != nil {
status = http.StatusInternalServerError
http.Error(w, "", status)
} else {
w.Write(pubKey)
}
default:
status = http.StatusNotFound
}
}
log.Println(req.RemoteAddr, req.Method, req.RequestURI, status)
}
func main() {
log.SetFlags(0)
var listenOn string
flag.StringVar(&listenOn, "l", "127.0.0.1:8080", "address:port")
flag.Parse()
log.Println("Listening on:", listenOn)
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(listenOn, nil))
}
# ensure requests get routed from libvirt VMs to service
# running as regular user on 127.0.0.1:8080
sysctl -w net.ipv4.conf.virbr0.route_localnet=1
iptables -t nat -A PREROUTING -i virbr0 \
-p tcp -m tcp -d 169.254.169.254/32 --dport 80 \
-j DNAT --to-destination 127.0.0.1:8080
ippatbles -i virbr0 -p tcp -m tcp \
-s 192.168.122.0/24 -d 127.0.0.1/32 \
--dport 8080 -j ACCEPT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment