Skip to content

Commit

Permalink
Release luks2crypt, linux cryptsetup key escrow client
Browse files Browse the repository at this point in the history
  • Loading branch information
Derek Tamsen committed May 18, 2018
0 parents commit 8cf3f98
Show file tree
Hide file tree
Showing 15 changed files with 1,506 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.git
vendor
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.DS_Store
luks2crypt
vendor
674 changes: 674 additions & 0 deletions COPYING

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
FROM golang:1.9

ARG LUKS2CRYPT_VER='7213ec6894a6f368375a290de81c17f56190c20e'
ARG DEP_VERSION='v0.3.2'

RUN adduser --shell /bin/sh --no-create-home --system --group \
--gecos 'golang build user' --disabled-password golang

RUN apt-get update && apt-get install -y \
libcryptsetup-dev \
curl \
&& curl -fsSL https://github.com/golang/dep/releases/download/${DEP_VERSION}/dep-linux-amd64 -o $GOPATH/bin/dep \
&& chmod +x $GOPATH/bin/dep \
&& apt-get remove -y curl \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

USER golang

RUN mkdir -p /go/src/github.com/square/luks2crypt
WORKDIR /go/src/github.com/square/luks2crypt

COPY Gopkg.toml Gopkg.lock ./
RUN dep ensure -vendor-only

COPY . .

# "go install -v ./..."
RUN go-wrapper install -ldflags "-X main.VERSION=${LUKS2CRYPT_VER}"

# ["app"]
ENTRYPOINT [ "go-wrapper", "run" ]
33 changes: 33 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"


[[constraint]]
branch = "master"
name = "github.com/dselans/dmidecode"

[[constraint]]
branch = "master"
name = "github.com/gorilla/schema"

[[constraint]]
name = "gopkg.in/urfave/cli.v1"
version = "1.20.0"

[[constraint]]
branch = "master"
name = "github.com/sethvargo/go-diceware"
14 changes: 14 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Copyright 2018 Square Inc.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
Luks2Crypt
==========

- https://golang.org/cmd/cgo/

- https://gitlab.com/cryptsetup/cryptsetup/blob/v1_6_6/lib/libcryptsetup.h

Luks2crypt is used to manage luks client devices and allow escrowing to a
[crypt-server](https://github.com/grahamgilbert/Crypt-Server). Currently, it
impliments some functionality similar to [Crypt2](https://github.com/grahamgilbert/crypt2).

`postimaging`:

- gathers system info (serial number, username, hostname)

- generates a random password

- test if the password passed in on the cli unlocks the disk

- caches the new password to `/etc/luks2crypt/crypt_recovery_key.json`

- uploads the new password to your local crypt-server

- changes the luks password passed in on the cli to the newly generated one

Dependencies
------------

Luks2crypt requires a pre-existing crypt-server to escrow keys. Crypt-server is
a Django web service for centrally storing recovery keys for full disk
encryption. See: https://github.com/grahamgilbert/Crypt-Server for more details.

Usage
-----

Setting the admin password and escrowing it post imaging:

sudo luks2crypt postimaging \
--luksdevice "<device_to_manage>" \
--currentpassword "<password_to_replace>" \
--cryptserver "<cryptserver.example.com>"

Development
-----------

- Install golang dep (https://github.com/golang/dep/blob/master/README.md)

- The cryptsetup libs are required to build. Cryptsetup C libraries are used
through cgo to manage the encrypted devices. On debian/ubuntu you can run:

sudo apt install libcryptsetup-dev

- Install deps required for project with `dep`:

dep ensure


License
-------

Copyright 2018 Square Inc.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
47 changes: 47 additions & 0 deletions escrow/escrow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2018 Square Inc.
//
// Use of this source code is governed by a GNU
// General Public License license version 3 that
// can be found in the LICENSE file.

package escrow

import (
"net/http"
"net/url"

"github.com/gorilla/schema"
)

// CryptServerInfo is used to create an object with info about the escrow server
type CryptServerInfo struct {
Server, URI string
}

// CryptServerData stores the data to be escrowed
type CryptServerData struct {
Pass string `schema:"recovery_password"`
Serialnum string `schema:"serial"`
Hostname string `schema:"macname"`
Username string `schema:"username"`
}

// PostCryptServer submits the luks password and machine info to crypt-server
func (data CryptServerData) PostCryptServer(escrowServer CryptServerInfo) (*http.Response, error) {
cryptServer := escrowServer.Server + escrowServer.URI

encoder := schema.NewEncoder()
form := url.Values{}

encodeErr := encoder.Encode(data, form)
if encodeErr != nil {
return nil, encodeErr
}

client := new(http.Client)
res, postErr := client.PostForm(cryptServer, form)
if postErr != nil {
return nil, postErr
}
return res, nil
}
85 changes: 85 additions & 0 deletions hwinfo/hwinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2018 Square Inc.
//
// Use of this source code is governed by a GNU
// General Public License license version 3 that
// can be found in the LICENSE file.

package hwinfo

import (
"errors"
"os"
"os/user"

"github.com/dselans/dmidecode"
)

// SystemInfo stores sys serial number, hostname, and username
type SystemInfo struct {
SerialNum, Hostname, Username string
}

// getSysSerialNumber returns the system serial number
func getSysSerialNumber() (string, error) {
dmi := dmidecode.New()

dmiRunErr := dmi.Run()
if dmiRunErr != nil {
return "", dmiRunErr
}

byNameData, byNameErr := dmi.SearchByName("System Information")
if byNameErr != nil {
return "", byNameErr
}

return byNameData["Serial Number"], nil
}

// getHostname returns the system hostname
func getHostname() (string, error) {
return os.Hostname()
}

// getUsername returns the current username
func getUsername() (string, error) {
username, err := user.Current()
return username.Username, err
}

// isRootUser returns true if we were run under root
func (sysinfo SystemInfo) isRootUser() bool {
if sysinfo.Username == "root" {
return true
}
return false
}

// Gather collects the system serial number, hostname, and current user
func Gather() (*SystemInfo, error) {
sysinfo := &SystemInfo{}

hostname, hostnameErr := getHostname()
if hostnameErr != nil {
return nil, hostnameErr
}
sysinfo.Hostname = hostname

username, usernameErr := getUsername()
if usernameErr != nil {
return nil, usernameErr
}
sysinfo.Username = username

if !sysinfo.isRootUser() {
return nil, errors.New("not supported under current user please use sudo")
}

serial, serialErr := getSysSerialNumber()
if serialErr != nil {
return nil, serialErr
}
sysinfo.SerialNum = serial

return sysinfo, nil
}
Loading

0 comments on commit 8cf3f98

Please sign in to comment.