feat(encryption): refactor encryption provider scripts, update KMS integration, and enhance key management
This commit is contained in:
+2
-1
@@ -42,4 +42,5 @@ drafts/*
|
|||||||
.molecule
|
.molecule
|
||||||
*.auto.tfvars
|
*.auto.tfvars
|
||||||
dev/*
|
dev/*
|
||||||
.ansible
|
.ansible
|
||||||
|
*.x.c
|
||||||
|
|||||||
@@ -138,9 +138,7 @@ encryption_volumes:
|
|||||||
mount_service_before: snap.microk8s.daemon-kubelite.service
|
mount_service_before: snap.microk8s.daemon-kubelite.service
|
||||||
mount_service_wantedby: snap.microk8s.daemon-kubelite.service
|
mount_service_wantedby: snap.microk8s.daemon-kubelite.service
|
||||||
mount_permission: "0755"
|
mount_permission: "0755"
|
||||||
encryption_aws_access_key_id: "{{ lookup('env', 'KMS_ACCESS_KEY') }}"
|
|
||||||
encryption_aws_secret_access_key: "{{ lookup('env', 'KMS_SECRET_KEY') }}"
|
|
||||||
encryption_kms_arn: "arn:aws:kms:eu-west-1:001604727293:key/977d08fd-8230-40bf-8a4f-d8a3264c5990"
|
|
||||||
encryption_kms_socket: /var/run/kmsplugin/socket.sock
|
encryption_kms_socket: /var/run/kmsplugin/socket.sock
|
||||||
|
|
||||||
# Kubernetes specific settings
|
# Kubernetes specific settings
|
||||||
|
|||||||
@@ -2,9 +2,4 @@
|
|||||||
encryption_volumes: []
|
encryption_volumes: []
|
||||||
encryption_volumes_path: /var/lib/encrypted_volumes
|
encryption_volumes_path: /var/lib/encrypted_volumes
|
||||||
encryption_volumes_default_size: 1G
|
encryption_volumes_default_size: 1G
|
||||||
|
|
||||||
encryption_aws_access_key_id:
|
|
||||||
encryption_aws_secret_access_key:
|
|
||||||
encryption_kms_arn:
|
|
||||||
encryption_kms_region: eu-west-1
|
|
||||||
encryption_kms_socket: /var/run/kmsplugin/socket.sock
|
encryption_kms_socket: /var/run/kmsplugin/socket.sock
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
if [ "$#" -ne 3 ]; then
|
if [ "$#" -ne 3 ]; then
|
||||||
echo "Usage: $0 <keyserver>" "<image>" "<device>"
|
echo "Usage: $0 <keyserver>" "<image>" "<device>"
|
||||||
|
echo "Example: $0 https://keyserver.example.com /path/to/image.img <device>"
|
||||||
|
echo "Example: $0 https://keyserver.example.com /path/to/image.img /dev/mapper/crypt1"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
if [ "$#" -lt 1 ]; then
|
||||||
|
echo "Usage: $0 <keyserver>" "[socket]"
|
||||||
|
echo "Example: $0 https://keyserver.example.com"
|
||||||
|
echo "Example: $0 https://keyserver.example.com /var/run/kmsplugin/socket.sock"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
KEYSERVER=$1
|
||||||
|
SOCKET=${2:-/var/run/kmsplugin/socket.sock}
|
||||||
|
|
||||||
|
# if keyserver is not reachable, exit
|
||||||
|
if ! curl -s -I $KEYSERVER > /dev/null; then
|
||||||
|
logger "start_encryption_provider: Key server not reachable, exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
uuid=$(cat /proc/cpuinfo | grep 'model name' | head -1)
|
||||||
|
uuid+=$(ip link show eth0 | grep ether | awk '{print $2}')
|
||||||
|
uuid+=$(sudo dmidecode -s system-uuid)
|
||||||
|
KEYID=$(echo -n "$uuid" | md5sum | awk '{print $1}')
|
||||||
|
|
||||||
|
logger "start_encryption_provider: Downloading key from key server,"
|
||||||
|
LOCALKEYFILE=$(mktemp)
|
||||||
|
curl -s -o $LOCALKEYFILE $KEYSERVER/$KEYID-encryption-service-credentials.json
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger "start_encryption_provider: Failed to download key from key server"
|
||||||
|
rm $LOCALKEYFILE
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
logger "start_encryption_provider: Key downloaded successfully, extracting credentials"
|
||||||
|
export AWS_ACCESS_KEY_ID=$(jq -r '.access_key' $LOCALKEYFILE)
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger "start_encryption_provider: Failed to extract AWS credentials from key file"
|
||||||
|
rm $LOCALKEYFILE
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export AWS_SECRET_ACCESS_KEY=$(jq -r '.secret_key' $LOCALKEYFILE)
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger "start_encryption_provider: Failed to extract AWS credentials from key file"
|
||||||
|
rm $LOCALKEYFILE
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
KEYARN=$(jq -r '.key_arn' $LOCALKEYFILE)
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger "start_encryption_provider: Failed to extract KMS key ARN from key file"
|
||||||
|
rm $LOCALKEYFILE
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
REGION=$(jq -r '.region' $LOCALKEYFILE)
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger "start_encryption_provider: Failed to extract region from key file"
|
||||||
|
rm $LOCALKEYFILE
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
logger "start_encryption_provider: Removing key file"
|
||||||
|
rm $LOCALKEYFILE
|
||||||
|
|
||||||
|
logger "start_encryption_provider: Starting encryption provider"
|
||||||
|
mkdir {{ encryption_kms_socket_dir | dirname }} }} 2>/dev/null || true
|
||||||
|
chmod 700 {{ encryption_kms_socket_dir | dirname }} 2>/dev/null
|
||||||
|
|
||||||
|
if [ ! -f /usr/local/bin/aws-encryption-provider ]; then
|
||||||
|
logger "start_encryption_provider: Encryption provider not found, exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
/usr/local/bin/aws-encryption-provider --key=$KEYARN --region=$REGION --listen=$SOCKET
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
logger "start_encryption_provider: Failed to start encryption provider"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
@@ -1,33 +1,16 @@
|
|||||||
- name: Check if required facts are set
|
|
||||||
ansible.builtin.fail:
|
|
||||||
msg: "The following variables are required: encryption_aws_access_key_id, encryption_aws_secret_access_key, encryption_kms_arn"
|
|
||||||
when:
|
|
||||||
- encryption_aws_access_key_id is not defined
|
|
||||||
- encryption_aws_secret_access_key is not defined
|
|
||||||
- encryption_kms_arn is not defined
|
|
||||||
|
|
||||||
- name: Copy aws-encryption-provider binary to the host
|
- name: Copy aws-encryption-provider binary to the host
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
src: aws-encryption-provider
|
src: aws-encryption-provider
|
||||||
dest: /usr/local/bin/aws-encryption-provider
|
dest: /usr/local/bin/aws-encryption-provider
|
||||||
mode: '0755'
|
mode: "0755"
|
||||||
|
|
||||||
- name: Copy start script to the host
|
|
||||||
become: true
|
|
||||||
ansible.builtin.template:
|
|
||||||
src: start-encryption-provider.sh.j2
|
|
||||||
dest: /usr/local/bin/start-encryption-provider.sh
|
|
||||||
mode: '0755'
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
|
|
||||||
- name: Create KMS socket directory
|
- name: Create KMS socket directory
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: /var/run/kmsplugin
|
path: /var/run/kmsplugin
|
||||||
state: directory
|
state: directory
|
||||||
mode: '0755'
|
mode: "0755"
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
|
|
||||||
@@ -36,7 +19,7 @@
|
|||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: aws-encryption-provider.service.j2
|
src: aws-encryption-provider.service.j2
|
||||||
dest: /etc/systemd/system/aws-encryption-provider.service
|
dest: /etc/systemd/system/aws-encryption-provider.service
|
||||||
mode: '0644'
|
mode: "0644"
|
||||||
|
|
||||||
- name: Reload systemd daemon
|
- name: Reload systemd daemon
|
||||||
become: true
|
become: true
|
||||||
|
|||||||
@@ -28,8 +28,9 @@
|
|||||||
dest: "/usr/local/bin/"
|
dest: "/usr/local/bin/"
|
||||||
mode: "0750"
|
mode: "0750"
|
||||||
with_items:
|
with_items:
|
||||||
- "open_volume"
|
- open_volume
|
||||||
- "read_system_id"
|
- read_system_id
|
||||||
|
- start_encryption_provider
|
||||||
tags:
|
tags:
|
||||||
- roles::encryption::volume
|
- roles::encryption::volume
|
||||||
|
|
||||||
@@ -43,6 +44,5 @@
|
|||||||
|
|
||||||
- name: Create KMS service
|
- name: Create KMS service
|
||||||
ansible.builtin.include_tasks: kms.yml
|
ansible.builtin.include_tasks: kms.yml
|
||||||
when: encryption_aws_access_key_id is defined and encryption_aws_secret_access_key is defined and encryption_kms_arn is defined
|
|
||||||
tags:
|
tags:
|
||||||
- roles::encryption::kms
|
- roles::encryption::kms
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Before=snap.microk8s.daemon-kubelite.service
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/local/bin/start-encryption-provider.sh
|
ExecStart=/usr/local/bin/start_encryption_provider "{{ key_server }}" "{{ encryption_kms_socket }}"
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
User=root
|
User=root
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# This script is used to start the encryption provider for the application.
|
|
||||||
# Managed by Ansible.
|
|
||||||
export AWS_ACCESS_KEY_ID={{ encryption_aws_access_key_id }}
|
|
||||||
export AWS_SECRET_ACCESS_KEY={{ encryption_aws_secret_access_key }}
|
|
||||||
/usr/local/bin/aws-encryption-provider --key={{ encryption_kms_arn }} --region={{ encryption_kms_region }} --listen={{ encryption_kms_socket }}
|
|
||||||
@@ -4,3 +4,15 @@ resource "scaleway_object" "system_id_encryption_key" {
|
|||||||
|
|
||||||
content_base64 = base64encode(var.encryption_key)
|
content_base64 = base64encode(var.encryption_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "scaleway_object" "system_id_encryption_aws_credentials" {
|
||||||
|
bucket = scaleway_object_bucket.infra_assets.id
|
||||||
|
key = "keys/${var.system_id}-encryption-service-credentials.json"
|
||||||
|
|
||||||
|
content = jsonencode({
|
||||||
|
access_key = var.kms_access_key
|
||||||
|
secret_key = var.kms_secret_key
|
||||||
|
region = "eu-west-1"
|
||||||
|
key_arn = var.kms_key_arn
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,3 +7,6 @@ TF_VAR_scaleway_organization_id=$SCALEWAY_ORGANIZATION_ID
|
|||||||
TF_VAR_scaleway_user_id=$SCALEWAY_USER_ID
|
TF_VAR_scaleway_user_id=$SCALEWAY_USER_ID
|
||||||
TF_VAR_bucket_suffix=$BUCKET_SUFFIX
|
TF_VAR_bucket_suffix=$BUCKET_SUFFIX
|
||||||
TF_VAR_encryption_key=$ENCRYPT_KEY
|
TF_VAR_encryption_key=$ENCRYPT_KEY
|
||||||
|
TF_VAR_kms_access_key=$KMS_ACCESS_KEY
|
||||||
|
TF_VAR_kms_secret_key=$KMS_SECRET_KEY
|
||||||
|
TF_VAR_kms_key_arn=$KMS_KEY_ARN
|
||||||
@@ -45,3 +45,21 @@ variable "system_id" {
|
|||||||
type = string
|
type = string
|
||||||
sensitive = true
|
sensitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "kms_access_key" {
|
||||||
|
description = "KMS User Access key"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "kms_secret_key" {
|
||||||
|
description = "KMS User Secret key"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "kms_key_arn" {
|
||||||
|
description = "KMS Access key ARN"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
BINARY=open_volume
|
||||||
|
|
||||||
|
.PHONY: all build clean
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build -o $(BINARY) main.go
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(BINARY)
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func usage() {
|
||||||
|
fmt.Printf("Usage: %s <keyserver> <image> <device>\n", os.Args[0])
|
||||||
|
fmt.Printf("Example: %s https://keyserver.example.com /path/to/image.img <device>\n", os.Args[0])
|
||||||
|
fmt.Printf("Example: %s https://keyserver.example.com /path/to/image.img /dev/mapper/crypt1\n", os.Args[0])
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileExists(path string) bool {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func deviceExists(device string) bool {
|
||||||
|
_, err := os.Stat("/dev/mapper/" + device)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func keyserverReachable(url string) bool {
|
||||||
|
resp, err := http.Head(url)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
resp.Body.Close()
|
||||||
|
return resp.StatusCode < 400
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUUID() string {
|
||||||
|
// Get CPU model name
|
||||||
|
cpuinfo, _ := ioutil.ReadFile("/proc/cpuinfo")
|
||||||
|
var model string
|
||||||
|
for _, line := range strings.Split(string(cpuinfo), "\n") {
|
||||||
|
if strings.HasPrefix(line, "model name") {
|
||||||
|
model = line
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get eth0 MAC address
|
||||||
|
iface, err := net.InterfaceByName("eth0")
|
||||||
|
mac := ""
|
||||||
|
if err == nil {
|
||||||
|
mac = iface.HardwareAddr.String()
|
||||||
|
}
|
||||||
|
// Get system UUID
|
||||||
|
out, _ := exec.Command("sudo", "dmidecode", "-s", "system-uuid").Output()
|
||||||
|
sysuuid := strings.TrimSpace(string(out))
|
||||||
|
uuid := model + mac + sysuuid
|
||||||
|
return uuid
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.SetFlags(0)
|
||||||
|
if len(os.Args) != 4 {
|
||||||
|
usage()
|
||||||
|
}
|
||||||
|
keyserver := os.Args[1]
|
||||||
|
image := os.Args[2]
|
||||||
|
device := os.Args[3]
|
||||||
|
|
||||||
|
if !fileExists(image) {
|
||||||
|
log.Printf("open_volume: (%s) Image file not found", device)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !keyserverReachable(keyserver) {
|
||||||
|
log.Printf("open_volume: (%s) Key server not reachable, exiting.", device)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if deviceExists(device) {
|
||||||
|
fmt.Printf("open_volume: (%s) Device already open, exiting.\n", device)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
uuid := getUUID()
|
||||||
|
h := md5.Sum([]byte(uuid))
|
||||||
|
keyid := hex.EncodeToString(h[:])
|
||||||
|
|
||||||
|
log.Printf("open_volume: (%s) Downloading key from key server,", device)
|
||||||
|
keyurl := fmt.Sprintf("%s/%s", keyserver, keyid)
|
||||||
|
resp, err := http.Get(keyurl)
|
||||||
|
if err != nil || resp.StatusCode != 200 {
|
||||||
|
log.Printf("open_volume: (%s) Failed to download key from key server", device)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
tmpfile, err := ioutil.TempFile("", "keyfile")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("open_volume: (%s) Failed to create temp file", device)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer os.Remove(tmpfile.Name())
|
||||||
|
_, err = io.Copy(tmpfile, resp.Body)
|
||||||
|
tmpfile.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("open_volume: (%s) Failed to save key file", device)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("open_volume:'%s' Key downloaded successfully, opening volume", device)
|
||||||
|
cmd := exec.Command("/usr/sbin/cryptsetup", "luksOpen", image, device, "-d", tmpfile.Name())
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("open_volume: (%s) Failed to open volume: %s", device, string(out))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("open_volume: (%s) Volume opened successfully, removing key file", device)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
BINARY=read_system_id
|
||||||
|
|
||||||
|
.PHONY: all build clean
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build -o $(BINARY) main.go
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(BINARY)
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getModelName() string {
|
||||||
|
file, err := os.Open("/proc/cpuinfo")
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
re := regexp.MustCompile(`^model name\s*:\s*(.*)$`)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if matches := re.FindStringSubmatch(line); matches != nil {
|
||||||
|
return matches[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEth0Mac() string {
|
||||||
|
out, err := exec.Command("ip", "link").Output()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
re := regexp.MustCompile(`^(\d+):\s+([a-zA-Z0-9]+):.*<.*>\s+link/ether\s+([0-9a-f:]{17})`)
|
||||||
|
matches := re.FindAllStringSubmatch(string(out), -1)
|
||||||
|
fmt.Println("Matches:", matches)
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
first_device := matches[0][2]
|
||||||
|
fmt.Println("First device:", first_device)
|
||||||
|
// Get the MAC address of the first device
|
||||||
|
out, err = exec.Command("ip", "link", "show", first_device).Output()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
re = regexp.MustCompile(`ether\s+([0-9a-f:]{17})`)
|
||||||
|
match := re.FindStringSubmatch(string(out))
|
||||||
|
if match != nil {
|
||||||
|
return match[1]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSystemUUID() string {
|
||||||
|
out, err := exec.Command("sudo", "dmidecode", "-s", "system-uuid").Output()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(string(out))
|
||||||
|
}
|
||||||
|
|
||||||
|
func md5sum(s string) string {
|
||||||
|
h := md5.New()
|
||||||
|
io.WriteString(h, s)
|
||||||
|
return hex.EncodeToString(h.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
uuid := getModelName()
|
||||||
|
uuid += getEth0Mac()
|
||||||
|
uuid += getSystemUUID()
|
||||||
|
fmt.Println(uuid)
|
||||||
|
hash := md5sum(uuid)
|
||||||
|
fmt.Println(hash)
|
||||||
|
}
|
||||||
Executable
+6
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
uuid=$(cat /proc/cpuinfo | grep 'model name' | head -1)
|
||||||
|
uuid+=$(ip link show wlo1 | grep ether | awk '{print $2}')
|
||||||
|
uuid+=$(sudo dmidecode -s system-uuid)
|
||||||
|
echo "UUID: $uuid"
|
||||||
|
echo -n "$uuid" | md5sum | awk '{print $1}'
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
BINARY=start_encryption_provider
|
||||||
|
|
||||||
|
.PHONY: all build clean
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build -o $(BINARY) main.go
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(BINARY)
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Credentials struct {
|
||||||
|
AccessKey string `json:"access_key"`
|
||||||
|
SecretKey string `json:"secret_key"`
|
||||||
|
KeyArn string `json:"key_arn"`
|
||||||
|
Region string `json:"region"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
fmt.Printf("Usage: %s <keyserver> [socket]\n", os.Args[0])
|
||||||
|
fmt.Printf("Example: %s https://keyserver.example.com\n", os.Args[0])
|
||||||
|
fmt.Printf("Example: %s https://keyserver.example.com /var/run/kmsplugin/socket.sock\n", os.Args[0])
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyserver := os.Args[1]
|
||||||
|
socket := "/var/run/kmsplugin/socket.sock"
|
||||||
|
if len(os.Args) > 2 {
|
||||||
|
socket = os.Args[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if keyserver is reachable
|
||||||
|
resp, err := http.Head(keyserver)
|
||||||
|
if err != nil || resp.StatusCode >= 400 {
|
||||||
|
log.Println("Key server not reachable, exiting.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate UUID
|
||||||
|
uuid := getCPUModel() + getEth0MAC() + getSystemUUID()
|
||||||
|
keyID := md5sum(uuid)
|
||||||
|
|
||||||
|
log.Println("Downloading key from key server")
|
||||||
|
keyURL := fmt.Sprintf("%s/%s-encryption-service-credentials.json", keyserver, keyID)
|
||||||
|
resp, err = http.Get(keyURL)
|
||||||
|
if err != nil || resp.StatusCode != 200 {
|
||||||
|
log.Println("Failed to download key from key server")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := io.ReadAll(resp.Body) // Changed from ioutil.ReadAll
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Failed to read key file")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var creds Credentials
|
||||||
|
if err := json.Unmarshal(body, &creds); err != nil {
|
||||||
|
log.Println("Failed to extract credentials from key file")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Setenv("AWS_ACCESS_KEY_ID", creds.AccessKey)
|
||||||
|
os.Setenv("AWS_SECRET_ACCESS_KEY", creds.SecretKey)
|
||||||
|
|
||||||
|
// Prepare socket dir
|
||||||
|
socketDir := filepath.Dir(socket)
|
||||||
|
os.MkdirAll(socketDir, 0700)
|
||||||
|
os.Chmod(socketDir, 0700)
|
||||||
|
|
||||||
|
if _, err := os.Stat("/usr/local/bin/aws-encryption-provider"); os.IsNotExist(err) {
|
||||||
|
log.Println("Encryption provider not found, exiting.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("/usr/local/bin/aws-encryption-provider",
|
||||||
|
"--key="+creds.KeyArn,
|
||||||
|
"--region="+creds.Region,
|
||||||
|
"--listen="+socket,
|
||||||
|
)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Println("Failed to start encryption provider")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCPUModel() string {
|
||||||
|
data, err := os.ReadFile("/proc/cpuinfo") // Changed from ioutil.ReadFile
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
for _, line := range strings.Split(string(data), "\n") {
|
||||||
|
if strings.HasPrefix(line, "model name") {
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEth0MAC() string {
|
||||||
|
iface, err := net.InterfaceByName("eth0")
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return iface.HardwareAddr.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSystemUUID() string {
|
||||||
|
out, err := exec.Command("sudo", "dmidecode", "-s", "system-uuid").Output()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(string(out))
|
||||||
|
}
|
||||||
|
|
||||||
|
func md5sum(s string) string {
|
||||||
|
h := md5.New()
|
||||||
|
io.WriteString(h, s)
|
||||||
|
return hex.EncodeToString(h.Sum(nil))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user