On the Edge Systems Administration with Golang

128
October 29–November 3, 2017 | San Francisco, CA www.usenix.org/lisa17 #lisa17 Close to the Edge Systems Administration in Go Chris "mac" McEniry https://app.strigo.io/event/iEHzHx4rhedZsJyTQ token: XGVI slack: #2017-tutorial-t1-go

Transcript of On the Edge Systems Administration with Golang

Page 1: On the Edge Systems Administration with Golang

October 29–November 3, 2017 | San Francisco, CAwww.usenix.org/lisa17 #lisa17

Close to the Edge Systems Administration in Go

Chris "mac" McEniry

https://app.strigo.io/event/iEHzHx4rhedZsJyTQ

token: XGVI

slack: #2017-tutorial-t1-go

Page 2: On the Edge Systems Administration with Golang

Administrivia

Page 3: On the Edge Systems Administration with Golang

Goals for Today• Sysadmin Topics

• File systems, Web Servers, One-liners, Containers, SSH

• Go Language Features

• Interfaces, Type Assertions, Function Types, Anonymous Functions, Empty Interface, Anonymous Structs, GOOS, GOARCH

• Go Libraries

• filepath, os, syscall, syscall, syscall, crypto/x509, crypto/tls, net/http, encoding/json, expvar, x/crypto/ssh

• Go Tools (in Go or for use on Go)

• go-bindata, go-bindata-assetfs, h2i, h2c, dep, gorram, expvarmon |

3

Page 4: On the Edge Systems Administration with Golang

Prerequisites• Some Go experience

• Mainly need to be able to read code and follow the basic control flow

4

Page 5: On the Edge Systems Administration with Golang

Schedule

9:00 - 9:10 Administrivia

9:10 - 9:20 Introduction

9:20 - 10:30 Interfaces, Files, Web Servers, TLS, HTTP/2

10:30 - 11:00 Break

11:00 - 12:30 JSON, Package Management, One Liners, Cross compilation, Metrics, Containers, SSH

5

Page 6: On the Edge Systems Administration with Golang

WARNING

Going to cut some corners with our code.

Any errors that arise - just going to panic.

This is not what you want to normally do - this is just for the sake of demonstration.

DO NOT USE ANY OF THIS CODE IN PRODUCTION WITHOUT TAKING A SECOND

LOOK AT IT

6https://pixabay.com/en/animals-black-and-white-bomb-boom-985500/

Page 7: On the Edge Systems Administration with Golang

Working with the Examples

• `go get github.com/cmceniry/cttesa`

• All exercises are meant to work with `go run`

• We'll continue after any example when ~50% of the attendees say to continue (by show of hands)

7

https://app.strigo.io/

Page 8: On the Edge Systems Administration with Golang

Close to the Edge...

Page 9: On the Edge Systems Administration with Golang

What do you remember as your

most ingenious moment?

9https://pixabay.com/p-1872376/?no_redirect

Page 10: On the Edge Systems Administration with Golang

• Built something

• Completed something

• Used something in a way it wasn't intended

• Succeeded even though you were blocked

• Learned something

10https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Mr_pipo_Learning.svg/1000px-Mr_pipo_Learning.svg.png

Page 11: On the Edge Systems Administration with Golang

"the quality of being clever, original, and

inventive."

11https://www.google.com/search?q=ingenuity

Page 12: On the Edge Systems Administration with Golang

David Blank-Edelman's

Over the Edge Systems Administration

Homage

12https://c1.staticflickr.com/7/6004/6013286848_c9d1782d7f_b.jpg

Page 13: On the Edge Systems Administration with Golang

• Generalize

• Use a new interface

• Repurpose your tools

• Do the smallest or wrong thing

• Transports and Tunnels

Over the Edge System Administration

13https://pixabay.com/p-1966997

Page 14: On the Edge Systems Administration with Golang

Close to the Edge• Experiment

• Sometimes you do it the hard way

• Look under the hood

• Read the code

• Read the docs

• Have fun

14https://pixabay.com/p-759080

Page 15: On the Edge Systems Administration with Golang

• Look at your tools. What do they tell you about themselves?

• Look at what your tools are operating on. What do the tools tell you about what they operate on?

• What do the tools tell you about how you do work?

15

Page 16: On the Edge Systems Administration with Golang

Let's get started...16

https://pixabay.com/p-1414148/?no_redirect

Page 17: On the Edge Systems Administration with Golang

17https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/Interface_logo.svg/1280px-Interface_logo.svg.png

Page 18: On the Edge Systems Administration with Golang

Go Types• Most Go Types represent some form of data

• Boolean, Numeric, String, Array, Slice, Struct, Pointer, Map, Channel

• The Interface Type represents behavior

• Bit of a placeholder

• "Any value whose type has these methods can be used here."

• "Any value whose type can do at least what I need of it can be used here."

• Can only use the methods of that interface

• This is used a lot without even knowing it

18

Page 19: On the Edge Systems Administration with Golang

io.Reader• Implements just one method: Read

• https://golang.org/pkg/io/#Reader

• godoc io | grep -A2 -m2 '^type Reader'

• Side note: error is an Interface Type. It implements `Error() string`

19

type Reader interface { Read(p []byte) (n int, err error)}

Page 20: On the Edge Systems Administration with Golang

cttesa/interface

• Can only call `Read([]byte) (int,error)` on `data`

• But that's all we need

func saveFile(filename string, data io.Reader) error { ...   nr, err := data.Read(buf) ...}

20

Page 21: On the Edge Systems Administration with Golang

cttesa/interface

• `a` and `b` are different different types, but both satisfy `io.Reader` so can be used for `saveFile`

func main() {    a := bytes.NewBuffer([]byte("file1\n"))    err := saveFile("file1", a) ...    b := strings.NewReader("file2\n")    err = saveFile("file2", b) ...}

21

Page 22: On the Edge Systems Administration with Golang

Another io.Reader• Find another io.Reader from the library

• Use saveFile to write it to disk

22

Page 23: On the Edge Systems Administration with Golang

Working with file metadata...23

https://upload.wikimedia.org/wikipedia/commons/c/c2/Logo_X-FILES.png

Page 24: On the Edge Systems Administration with Golang

syscall.Stat_t• Goal: Get the inode for a file

• Go concept: Type Assertion, syscall.Stat_t

24

Page 25: On the Edge Systems Administration with Golang

cttesa/inode

• `s.Sys()` returns a interface which must be asserted to `*syscall.Stat_t`

• `*syscall.Stat_t` struct has actual the `Ino` field

func getInode(path string) (uint64, error) {    s, err := os.Stat(path) ...    stat, ok := s.Sys().(*syscall.Stat_t) ...    return stat.Ino, nil}

25

Page 26: On the Edge Systems Administration with Golang

filepath.Walk• Goal: Locate files with the same Inode

• Go concepts: Function Type, filepath.Walk

26

Page 27: On the Edge Systems Administration with Golang

cttesa/inode-walk

• The `filepath` library defines a `WalkFunc` Function Type to be used to define any custom logic for it. We can define that and provide it to the `Walk` function.

type WalkFunc func(path string, info os.FileInfo, err error) error...func Walk(root string, walkFn WalkFunc) error

27

func walkFunc(path string, info os.FileInfo, err error) error {...fun main() { filepath.Walk(".", walkFunc)

Page 28: On the Edge Systems Administration with Golang

Anonymous Function• You don't have to define the function. It can be used as an expression inline -

this is called an Anonymous Function

• Complete `inode-anon` to use an anonymous function. Copy portions from `inode-walk`

• Place the Println to add a prefix defined in the `main` function

28

func main() {    prefix := "FOUND:"    filepath.Walk(".", ...) // fmt.Printf("%s %s = %d\n", prefix, path, ino)}

Page 29: On the Edge Systems Administration with Golang

Why Anonymous Functions?• Inline

• Locate code closer to where it is used

• If only used once, no reason to separate it

• Allows for closures

• Wrapping up of variables

• Access to inside of function which wouldn't be available otherwise

29

Page 30: On the Edge Systems Administration with Golang

Returning Anonymous Function• Advanced: Do-on-your-own challenge..

• Write a function which takes in a string, the prefix, and returns a `filepath.WalkFunc`

• Update `inode-anon` to use this function

• Behaves the same as `inode-walk`

30

Page 31: On the Edge Systems Administration with Golang

Need to serve files somehow..31

https://upload.wikimedia.org/wikipedia/commons/thumb/b/b5/Kickstarter_logo.svg/2000px-Kickstarter_logo.svg.png

Page 32: On the Edge Systems Administration with Golang

cttesa/kickstart• Goal: Deploy a web server to handle static files

• Go concepts: net/http, +Function Type, +Interface

32

Page 33: On the Edge Systems Administration with Golang

33

https://golang.org/pkg/net/http/#Handle

https://golang.org/pkg/net/http/#FileServer

https://golang.org/pkg/net/http/#FileSystem

Page 34: On the Edge Systems Administration with Golang

34

https://golang.org/pkg/net/http/#Dir

==> An http.Dir value (acts as http.FileSystem) can be fed to http.FileServer ==> http.FileServer returns an http.Handler which can be fed to http.Handle

Page 35: On the Edge Systems Administration with Golang

Setup the static server• Fill in `kickstart` with the appropriate line so that it will serve the files in the

`data` directory

35

func main() { ...    fmt.Println("Listening on :8080")    http.ListenAndServe(":8080", nil)}

Page 36: On the Edge Systems Administration with Golang

• Goal: Make the file server stand alone

• Go concepts: go generate, go-bindata-assetfs

36

Page 37: On the Edge Systems Administration with Golang

Single binary• One of Go's strengths is its ability to package up as a single binary.

• What if you could package up resources in that binary as well?

37

Page 38: On the Edge Systems Administration with Golang

38

https://github.com/elazarl/go-bindata-assetfs

Page 39: On the Edge Systems Administration with Golang

go-bindata-assetfs data/...cat bindata_assetfs.go...func assetFS() *assetfs.AssetFS { assetInfo := func(path string) (os.FileInfo, error) { return os.Stat(path) } for k := range _bintree.Children { return &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, AssetInfo: assetInfo, Prefix: k} }

cttesa/kickstart-embedded

39

Page 40: On the Edge Systems Administration with Golang

40

https://godoc.org/github.com/elazarl/go-bindata-assetfs#AssetFS

Look familiar?

Page 41: On the Edge Systems Administration with Golang

go generate• Part of build tool which runs prior to build

• Can trigger manually with `go generate`

• Executes what's in a generate comment

• Intention is for any code generation pieces

41

//go:generate echo foo

Page 42: On the Edge Systems Administration with Golang

Setup Generate and assetFS• Update `kickstart-embedded` to use `assetFS`

• Update `kickstart-embedded` to generate automatically

• Build/run stand alone web server

42

Page 43: On the Edge Systems Administration with Golang

Encryption43

https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/TLS_in_TCPIP_stack.svg/500px-TLS_in_TCPIP_stack.svg.png

Page 44: On the Edge Systems Administration with Golang

• Goal: Add encryption to the web server

• Go concept: net/http.Server, crypto/tls, crypto/x509

44

Page 45: On the Edge Systems Administration with Golang

Custom http server configuration• Been using the default http server in net/http

• Can setup custom http servers - different configs, multiple at once, etc

• Define the server as a value and use that instead of the default library functions

45

http.ListenAndServe(":8080", nil)

s := http.Server{Addr: ":8080"}err = s.ListenAndServe()

Page 46: On the Edge Systems Administration with Golang

Generate certificates• Process

• Generate Private Key

• Generate Certificate Information

• Self-sign Certificate with Private Key

• Everything else is just manipulating it so the libraries take it

46

Page 47: On the Edge Systems Administration with Golang

Two Certificate Types• crypto/x509.Certificate: Used for general certificate information

• crypto/tls.Certificate: Used for certificates in the context of TLS

• Support for Cert/Key together

• Support for name/Cert mapping

• Support for Certificate chain required by TLS

47

Page 48: On the Edge Systems Administration with Golang

48

https://golang.org/pkg/crypto/x509/#Certificate

https://golang.org/pkg/crypto/tls/#Certificate

Page 49: On the Edge Systems Administration with Golang

TLS Certificates• Need to generate the certificate using crypto/x509

• Then format it into crypto/tls

49

Page 50: On the Edge Systems Administration with Golang

cttesa/tls• Has a helper function : generateTLSCert

• Returns the tls.Certificate since that is what is used later

• Start by generating the private key

• Next go into certificate information...

50

func generateTLSCert() (*tls.Certificate, error) {

    k, err := rsa.GenerateKey(rand.Reader, 2048)

Page 51: On the Edge Systems Administration with Golang

51

t := x509.Certificate{    SerialNumber: big.NewInt(1),    Subject: pkix.Name{CommonName: "localhost"},    NotBefore: time.Now().Add(-30 * time.Second),    NotAfter: time.Now().Add(86400 * time.Second),    KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,    ExtKeyUsage: []x509.ExtKeyUsage{        x509.ExtKeyUsageServerAuth,    },}

cttesa/tls

Page 52: On the Edge Systems Administration with Golang

• Next step is to sign the certificate (see exercise). Need an crypto/x509 function that returns a certificate format (type or bytes or...)

52

https://golang.org/pkg/crypto/x509/#CreateCertificate

Page 53: On the Edge Systems Administration with Golang

• Then need to format it for tls.Certificate (PEM vs DER). Looking at the crypto/tls library, we look for a function which returns a Certificate.

53

https://golang.org/pkg/crypto/tls/#X509KeyPair

Page 54: On the Edge Systems Administration with Golang

cttesa/tls• We need to format the cert and key into a pem []byte

certPem := pem.EncodeToMemory(&pem.Block{    Type: "CERTIFICATE",    Bytes: c,})keyPem := pem.EncodeToMemory(&pem.Block{    Type: "RSA PRIVATE KEY",    Bytes: x509.MarshalPKCS1PrivateKey(k),})

54

Page 55: On the Edge Systems Administration with Golang

cttesa/tls• Setup the handler as before

• Setup the net/http.Server value, with a crypto/tls.Config wired up to it.

• And then can start the listen and serve loop, though in this case, it's ListenAndServerTLS

err = s.ListenAndServeTLS("", "")

55

http.Handle("/", http.FileServer(http.Dir(".")))

s := http.Server{...}

Page 56: On the Edge Systems Administration with Golang

56

https://golang.org/pkg/net/http/#Server

https://golang.org/pkg/crypto/tls/#Config

Page 57: On the Edge Systems Administration with Golang

Generating Certs and Enabling TLS• Complete `tls/main.go` by

• making the appropriate call to generate the x509.Certificate

• making the appropriate call to generate the tls.Certificate

• making the appropriate call to configure TLS

• Can skip hostname verification

• Listen on localhost:8443

57

Page 58: On the Edge Systems Administration with Golang

Can generate as files...• https://golang.org/src/crypto/tls/generate_cert.go

58

Page 59: On the Edge Systems Administration with Golang

http259

Page 60: On the Edge Systems Administration with Golang

• Goal: Setup for HTTP/2

• Go concept: h2i, h2c, net/http

60

Page 61: On the Edge Systems Administration with Golang

HTTP/2• Binary protocol

• Required encryption

• Multiplexing of requests

• Header compression

• Wraps (essentially) HTTP/1.1 requests into frames

61

Page 62: On the Edge Systems Administration with Golang

• Golang's net/http library already has HTTP/2 built in (if you run TLS)

• Several tools in Go to test it

• https://github.com/fstab/h2c

• https://godoc.org/golang.org/x/net/http2/h2i

62

Page 63: On the Edge Systems Administration with Golang

Access web server from h2i

63

shell$ h2i -insecure localhost:8443...h2i> headers(as HTTP/1.1)> GET / HTTP/1.1(as HTTP/1.1)>...

Page 64: On the Edge Systems Administration with Golang

Access web server from h2c

• Go back and restart the other kickstart examples. Try the same with localhost:8080

64

shell$ h2c start &...shell$ h2c connect localhost:8443shell$ h2c get /...shell$ h2c stop...

Page 65: On the Edge Systems Administration with Golang

Universal config files...65

https://c2.staticflickr.com/4/3880/14636491710_d347ce16ae_b.jpg

Page 66: On the Edge Systems Administration with Golang

Reading JSON• Goal: Load configuration data from a JSON structure

• Go concepts: Empty Interface{}, encoding/json

66

Page 67: On the Edge Systems Administration with Golang

Parsing JSON/XML/YAML• Golang's encoding libraries behave the same way

• Use reflection to determine how to convert data

• Or use `map[string]interface{}` to create for key/value with the value being non-specific types

67

Page 68: On the Edge Systems Administration with Golang

cttesa/json-empty• The JSON structure that we're going to work with

• We're going to just try to pull "bar" out.

{ "foo": 123, "bar": "baz", "really": true}

68

Page 69: On the Edge Systems Administration with Golang

cttesa/json-empty• Initialize a map to store data. Note the inline `interface{}` -- essentially an

anonymous interface definition

• Now use `json.Unmarshal` to load data into c from our source. Unmarshal works on a slice of bytes, so have to convert the string to allow it.

c := make(map[string]interface{})

69

json.Unmarshal([]byte(data1), &c)

Page 70: On the Edge Systems Administration with Golang

cttesa/json-empty• Now, safely get the data out

barEmpty, ok := c["bar"]if !ok {    panic("bar missing")}bar, ok := barEmpty.(string)if !ok {    panic("bar is not a string")}fmt.Printf("bar: %s\n", bar)

70

Page 71: On the Edge Systems Administration with Golang

Reading JSON using a struct• The constant conversion is fairly verbose.

• Can rely on the library to do the work for us.

71

Page 72: On the Edge Systems Administration with Golang

cttesa/json-struct• Need to define a struct type to hold the data and give form

• Then can decode the exact same way, but without the same checks

type config struct {    Foo int64    Bar string    Really bool}

72

c := &config{}json.Unmarshal([]byte(data1), &c)fmt.Printf("bar: %s\n", c.Bar)

Page 73: On the Edge Systems Administration with Golang

Read XML• Perform the same exercise with XML

• Complete `xml-struct`:

• Fill in the fields for `config` based on the XML input

• Call the right function to convert `data1` to `c`

73

Page 74: On the Edge Systems Administration with Golang

Writing JSON• Goal: Output JSON

• Go concepts: Anonymous Struct, Inline Initialization

74

Page 75: On the Edge Systems Administration with Golang

Writing JSON• Same reflection can be used to output JSON

• But you don't have to do any of the checking

• Becomes dealers choice for what to output from

• Existing or inline map[string]interface{}

• Existing or inline (anonymous) struct

75

Page 76: On the Edge Systems Administration with Golang

Writing JSON• Complete `json-output`

• All blocks should output a `Name` and `Value`

76

Page 77: On the Edge Systems Administration with Golang

Do the same with XML• On your own...

• Do `json-output`, but with encoding/xml instead of encoding/json

77

Page 78: On the Edge Systems Administration with Golang

Struct Tags• On your own...

• Investigate struct tags to map other fields into the structs

• E.g. a JSON field "common_name" needs to map to camelcase "CommonName" field inside of a struct

78

Page 79: On the Edge Systems Administration with Golang

dep79

https://c2.staticflickr.com/8/7165/6514584423_a9b13d6b70_b.jpg

Page 80: On the Edge Systems Administration with Golang

Pulling in Others' Code• So far, everything we used has been a command, so we didn't look at

dependencies, just used them via `go get...`

• Now we want to pull in an actual code dependency.

• In the previous JSON examples, we converted JSON to and from

• map of the empty interfaces

• structs

• What if we want to skip the JSON part?

80

Page 81: On the Edge Systems Administration with Golang

81

https://godoc.org/github.com/mitchellh/mapstructure

Why?

Some functions work with pluggable backends but have a common interface. That interface may or may not be able to use fix types and so have to resort to some more abstract pieces. It's still nice to be able to convert those.

Page 82: On the Edge Systems Administration with Golang

Go Package Management• Has be very limited*

• Several different package managers sprung up to fill the void

• Community finally started to push to a common one

• Still being sorted out, so this might change...

82

https://pixabay.com/p-311665

https://pixabay.com/p-307592

Page 83: On the Edge Systems Administration with Golang

dep• Command which will handle dependency

• Looks through your code, sees what is dependent (imports)

• Looks at the dependencies, see what they depend on, and repeat

• Takes some input as to if there are any constraints (library versions which you have said you are locked to)

• Solves to pull in the best version of dependencies

83

Page 84: On the Edge Systems Administration with Golang

dep Structure• `vendor` directory in project would keep all of the upstream dependencies

• `Gopkg.toml` has any constraints you want to put into it

• `Gopkg.lock` is the current state of the dependency solver

84

Page 85: On the Edge Systems Administration with Golang

dep Commands• `dep init`: Setup `Gopkg` and `vendor`

• `dep ensure`: Regularly keep dependencies in alignment

• Updates to your imports

• Updates to upstream version

• Updates to constraints

85

Page 86: On the Edge Systems Administration with Golang

Use map structure• Complete `dep/main.go`:

• Fill in the appropriate import statement

• Fill in the appropriate data conversion function

• Use `dep` to manage the dependency

• Expected out is similar to JSON exercises

86

shell$ go run main.goProperty1=100

Page 87: On the Edge Systems Administration with Golang

Golang "one-liners"87

http://www.urbandictionary.com/define.php?term=Gorram

Page 88: On the Edge Systems Administration with Golang

Golang Oneliners• The need for `main.main` makes it hard to do a oneliner in Go.

• However, if we make some assumptions about input and output, we can pull it off...

88

Page 89: On the Edge Systems Administration with Golang

89

Page 90: On the Edge Systems Administration with Golang

90

Lots of options for

inferring input/

output streams

Page 91: On the Edge Systems Administration with Golang

Play with gorram

91

shell$ gorram crypto/sha1 Sum /etc/hostsshell$ echo 12345 | gorram encoding/base64 StdEncoding.EncodeToStringshell$ # is there an equivalent to decode base64?shell$ gorram net/http Get https://www.usenix.org/conference/lisa17

shell$ gorram math/rand Intshell$ gorman math/rand Int # run this twice - what's up?

Page 92: On the Edge Systems Administration with Golang

Notes for the future...• Think about building library functions so that you can refer to them with

tools like Gorram

92

Page 93: On the Edge Systems Administration with Golang

expvar93

Page 94: On the Edge Systems Administration with Golang

• Goal: Monitoring Go processes

• Go concept: expvar

94

Page 95: On the Edge Systems Administration with Golang

95

https://golang.org/pkg/expvar/

Page 96: On the Edge Systems Administration with Golang

96

https://github.com/divan/expvarmon

Page 97: On the Edge Systems Administration with Golang

Use expvar• Instrument `kickstart` using expvar

• Use a browser or command line web client to get data from expvar endpoint

• Examine the metrics with `expvarmon`

97

Page 98: On the Edge Systems Administration with Golang

Caveats...• This is either a really good approach or a really bad approach - you have

to decide for yourself

• Can use different `net/http.Server` and `expvar.Handler` to move where the metrics are exposed (exercise for yourself)

98

Page 99: On the Edge Systems Administration with Golang

GOOS and GOARCH99

Page 100: On the Edge Systems Administration with Golang

Cross Compilation• The Go tool chain has cross compilation built in

• Can easily build on one platform for many platforms

• There are edges with cgo bindings and syscall specific items

• Use GOOS (pronounced goose) and GOARCH (garch) to control the target of the build

100

Page 101: On the Edge Systems Administration with Golang

cttesa/cc// +build darwin

101

// +build darwin,i386

// +build windows

// +build linux,amd64

Page 102: On the Edge Systems Administration with Golang

Attempt Cross Compile• `cc` has three files

• `main-darwin.go`

• `main-linux.go`

• `main-windows.go`

• Attempt to cross compile with various GOOS settings and see the results

102

shell$ GOOS=... go build .shell$ file cc*...

Page 103: On the Edge Systems Administration with Golang

Make your own containers...103

https://pixabay.com/p-1096829

Page 104: On the Edge Systems Administration with Golang

Containers• Goal: Build a limited container by hand

• Go concepts: os/exec, syscall

104

Page 105: On the Edge Systems Administration with Golang

Containers: The Short Short Version• Processes with:

• Isolation (namespaces) - Visibility

• Resource constraints (cgroups)

• Privileges (capabilities)

105

Page 106: On the Edge Systems Administration with Golang

e.g. chroot• The first partial namespace: chroot

• Would give you a different perspective to the root file system

• Extend this out to the full mnt ("ns") namespace, you can control completely different sets of mounts; not just one as a child of the other.

106

Page 107: On the Edge Systems Administration with Golang

Other Namespace• UTS - UNIX Timesharing System (aka hostname/domainname)

• Net

• PID

• IPC

• User

• Cgroup

107

Page 108: On the Edge Systems Administration with Golang

108

https://golang.org/pkg/os/exec/#Cmd

Page 109: On the Edge Systems Administration with Golang

cttesa/container• Containers are built on processes; new processes handled by os/

exec.Cmd

• Can connect process inputs and outputs (just like pipes and redirection)

• And start the command:

cmd := exec.Command("/bin/bash")

109

cmd.Stdin = os.Stdincmd.Stdout = os.Stdoutcmd.Stderr = os.Stderr

err := cmd.Run()

Page 110: On the Edge Systems Administration with Golang

110

https://golang.org/pkg/syscall/#SysProcAttr

Page 111: On the Edge Systems Administration with Golang

111

https://golang.org/pkg/syscall/#pkg-constants

Page 112: On the Edge Systems Administration with Golang

A couple of isolations...• Finish `container/main.go` by setting the appropriate field on `cmd`.

• Isolate hostname: Change the hostname inside and out and show no cross impact

• Isolate network: Run it and see the difference on `ip addr`

112

Page 113: On the Edge Systems Administration with Golang

ssh113

https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/SSH_Communications_Security_logo.svg/1280px-SSH_Communications_Security_logo.svg.png

Page 114: On the Edge Systems Administration with Golang

• Goal: Setting up ssh in code

• Go concepts: golang.org/x/crypto/ssh

114

Page 115: On the Edge Systems Administration with Golang

Using the ssh library• Three parts to using it

• Get any authentication credentials

• Setup the configuration and connect to the server

• Run session which execute the commands we use

115

Page 116: On the Edge Systems Administration with Golang

116

https://godoc.org/golang.org/x/crypto/ssh#Client

Page 117: On the Edge Systems Administration with Golang

117

https://godoc.org/golang.org/x/crypto/ssh#ClientConfig

Page 118: On the Edge Systems Administration with Golang

cttesa/ssh

• `getKey` gets the auth key needed for ssh key authentication

func getKey() (ssh.Signer) { keyFile := "/home/got/.ssh/id_rsa" pemKey, err := ioutil.ReadFile(keyFile) ... signer, err := ssh.ParsePrivateKey(pemKey) ... return signer}

118

Page 119: On the Edge Systems Administration with Golang

cttesa/ssh

• `connect` uses the auth key to connect to the localhost

func connect(host string, signer ssh.Signer) *ssh.Client { config := &ssh.ClientConfig{ User: "got", Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, HostKeyCallback: ssh.InsecureIgnoreHostKey(), } client, err := ssh.Dial("tcp", "127.0.0.1:22", config) ... return client

119

Page 120: On the Edge Systems Administration with Golang

120

https://godoc.org/golang.org/x/crypto/ssh

Page 121: On the Edge Systems Administration with Golang

cttesa/ssh• Start by opening a new session. This is for a single command to run

• As usual, we will want to clean up when we're done

• Connect our process to the remote command by pulling out a StdinPipe

session, err := client.NewSession()

121

defer session.Close()

sin, err := session.StdinPipe()

Page 122: On the Edge Systems Administration with Golang

cttesa/ssh• Start a command inside of the session

• Perform any needed actions

• Wait till the command finishes

err = session.Start(...)

122

session.Wait()

Page 123: On the Edge Systems Administration with Golang

"Copy" a file over ssh• Simulate the action of "echo input | ssh ..."

• Finish `ssh/main.go` to simulate the action of `echo input | ssh ...` to "copy" a file over ssh

• Fill in the command to execute on the remote side

• Pipe data over the ssh session (`io.Copy` will help)

123

Page 124: On the Edge Systems Administration with Golang

Wrap up124

https://pixabay.com/p-1090619

Page 125: On the Edge Systems Administration with Golang

Some laughter

Some thinking

Goals for today

125https://commons.wikimedia.org/wiki/Emoji#/media/File:Twemoji2_1f914.svghttps://commons.wikimedia.org/wiki/File:Twemoji2_1f602.svg

Page 126: On the Edge Systems Administration with Golang

Questions Inspired by each Exercise• Interface: How much do we rely on concrete aspects instead of behaviors?

• Files: How can we provide a smarter response to `find` results?

• Kickstart: Can we package *everything* that we need up into a nice package? What are the trade offs?

• TLS: Is it really that scary to be secure?

• http2: How much is already built into what we're using?

• JSON: How can we make data transformations easy?

126

Page 127: On the Edge Systems Administration with Golang

Questions Inspired by each Exercise• dep: What if other people wanted to use this?

• gorram: How do we structure our code so it's reusable, not just by other libraries, but also by other tools?

• expvar: Can (should?) we use our application ports for signaling and monitoring as well? What are the tradeoffs?

• GOOS/GOARCH: How portable is our code really?

• Containers: What does this tell us about the underlying system?

• SSH: Just because we're working code, are there other methods (e.g. shell-isms) that we can bring into our code?

127

Page 128: On the Edge Systems Administration with Golang

October 29–November 3, 2017 | San Francisco, CAwww.usenix.org/lisa17 #lisa17

Remember to fill in yourtutorial evaluation!

Thank You!

T1 - Close to the Edge Systems AdministrationChris "mac" McEniry