Skip to content

Commit

Permalink
Added controller subprocess
Browse files Browse the repository at this point in the history
  • Loading branch information
fire833 committed Mar 6, 2022
1 parent 75c6a0c commit b7aff2e
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 116 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
vendor/*
vendor

vroute
bin/

.vscode
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ all:

build:
@echo "Building control plane from source..."
@GOOS=linux GOARCH=amd64 go build -o bin/vroute cmd/vroute/main.go cmd/vroute/constants.go cmd/vroute/node.go cmd/vroute/api.go cmd/vroute/commands.go
@# GOOS=windows GOARCH=amd64 go build -o bin/vroute.exe cmd/vroute/main.go cmd/vroute/constants.go cmd/vroute/node.go cmd/vroute/api.go cmd/vroute/commands.go
@GOOS=linux GOARCH=arm64 go build -o bin/vroute-linux-arm64 cmd/vroute/main.go cmd/vroute/constants.go cmd/vroute/node.go cmd/vroute/api.go cmd/vroute/commands.go
@GOOS=linux GOARCH=arm go build -o bin/vroute-linux-arm cmd/vroute/main.go cmd/vroute/constants.go cmd/vroute/node.go cmd/vroute/api.go cmd/vroute/commands.go
@GOOS=linux GOARCH=amd64 go build -o bin/vroute cmd/vroute/main.go cmd/vroute/constants.go cmd/vroute/node.go cmd/vroute/api.go cmd/vroute/commands.go cmd/vroute/controller.go
@# GOOS=windows GOARCH=amd64 go build -o bin/vroute.exe cmd/vroute/main.go cmd/vroute/constants.go cmd/vroute/node.go cmd/vroute/api.go cmd/vroute/commands.go cmd/vroute/controller.go
@GOOS=linux GOARCH=arm64 go build -o bin/vroute-linux-arm64 cmd/vroute/main.go cmd/vroute/constants.go cmd/vroute/node.go cmd/vroute/api.go cmd/vroute/commands.go cmd/vroute/controller.go
@GOOS=linux GOARCH=arm go build -o bin/vroute-linux-arm cmd/vroute/main.go cmd/vroute/constants.go cmd/vroute/node.go cmd/vroute/api.go cmd/vroute/commands.go cmd/vroute/controller.go
@echo "Success!"
2 changes: 1 addition & 1 deletion cmd/vroute/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
)

// Unprivileged API listener main function.
func api_main() {
func apiMain() {

fmt.Printf("starting api process, dropping process privilege")

Expand Down
74 changes: 66 additions & 8 deletions cmd/vroute/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,21 @@ For more information about this project and for documentation, visit https://git
Run: forkNode,
Hidden: true,
}

forkControllerCmd = &cobra.Command{
Use: "controllerfork <runtime_token>",
Short: "Used for trusted forking of controller subprocess.",
Run: forkController,
Hidden: true,
}
)

// The main function for the vroute control plane.
func vrouteMain() {
rootCmd.Flags().BoolVar(&src.DebugEnabled, "debug", false, "Use this subcommand to enable debugging mode for the process.")
rootCmd.AddCommand(forkNodeCmd)
rootCmd.AddCommand(forkAPICmd)
rootCmd.AddCommand(forkControllerCmd)

if e := rootCmd.Execute(); e != nil {
log.Printf("Unable to start vroute: %v\n", e.Error())
Expand All @@ -79,7 +87,7 @@ func forkAPI(cmd *cobra.Command, args []string) {
// Compare the provided token to the root token to make sure this is a
// legitimately spawned process.
if args[2] == "-t" && args[3] == src.SharedToken.GetToken() {
api_main()
apiMain()
} else {
log.Printf("shared tokens do not match, aborting api fork\n")
os.Exit(1)
Expand All @@ -92,24 +100,47 @@ func forkNode(cmd *cobra.Command, args []string) {
// Compare the provided token to the root token to make sure this is a
// legitimately spawned process.
if args[2] == "-t" && args[3] == src.SharedToken.GetToken() {
node_main()
nodeMain()
} else {
log.Printf("shared tokens do not match, aborting node fork\n")
os.Exit(1)
}
}

func forkController(cmd *cobra.Command, args []string) {
// Compare the provided token to the root token to make sure this is a
// legitimately spawned process.
if args[2] == "-t" && args[3] == src.SharedToken.GetToken() {
controllerMain()
} else {
log.Printf("shared tokens do not match, aborting controller fork\n")
os.Exit(1)
}
}

func rootMain(cmd *cobra.Command, args []string) {

log.Printf("generating runtime trust tokens for bootstrapping daughter processes")
src.GenerateRuntimeTrustAnchors()

log.Printf("forking node process...\n")

vroute, e := os.Executable()
if e != nil {
log.Printf("unable to acquire path to vroute executable: %v, exiting...\n", e)
os.Exit(1)
}

// Spawn the node process first
nodepid, nodee := syscall.ForkExec("vroute", []string{"forknode", "-t", src.SharedToken.GetToken()}, &syscall.ProcAttr{
nodepid, nodee := syscall.ForkExec(vroute, []string{"forknode", "-t", src.SharedToken.GetToken()}, &syscall.ProcAttr{
Sys: &syscall.SysProcAttr{
Ptrace: false,
Cloneflags: syscall.CLONE_NEWIPC,
Credential: &syscall.Credential{},
Cloneflags: syscall.CLONE_NEWIPC | syscall.CLONE_VM,
Credential: &syscall.Credential{
Uid: uint32(rootUID),
Gid: uint32(rootGID),
NoSetGroups: true,
},
},
})

Expand All @@ -120,12 +151,18 @@ func rootMain(cmd *cobra.Command, args []string) {
log.Printf("vroute node process created, PID: %d\n", nodepid)
}

log.Printf("forking api process...\n")

// Spawn the api server second
apipid, apie := syscall.ForkExec("vroute", []string{"forkapi", "-t", src.SharedToken.GetToken()}, &syscall.ProcAttr{
apipid, apie := syscall.ForkExec(vroute, []string{"forkapi", "-t", src.SharedToken.GetToken()}, &syscall.ProcAttr{
Sys: &syscall.SysProcAttr{
Ptrace: false,
Cloneflags: syscall.CLONE_NEWIPC,
Credential: &syscall.Credential{},
Cloneflags: syscall.CLONE_NEWIPC | syscall.CLONE_VM,
Credential: &syscall.Credential{
Uid: uint32(unprivilegedUID),
Gid: uint32(unprivilegedGID),
NoSetGroups: true,
},
},
})

Expand All @@ -136,6 +173,27 @@ func rootMain(cmd *cobra.Command, args []string) {
log.Printf("vroute api process created, PID: %d\n", apipid)
}

log.Printf("forking controller process...\n")

// Spawn controller manager third.
controllerpid, controllere := syscall.ForkExec(vroute, []string{"forkcontroller", "-t", src.SharedToken.GetToken()}, &syscall.ProcAttr{
Sys: &syscall.SysProcAttr{
Ptrace: false,
Cloneflags: syscall.CLONE_NEWIPC | syscall.CLONE_VM,
Credential: &syscall.Credential{
Uid: uint32(unprivilegedUID),
Gid: uint32(unprivilegedGID),
NoSetGroups: true,
},
}})

if controllere != nil {
log.Printf("unable to fork controller process, error: %v\n", controllere.Error())
os.Exit(1)
} else {
log.Printf("vroute controller process created, PID: %d\n", controllerpid)
}

log.Printf("vroute control plane bootstrapped, bootstrap process exiting")

}
78 changes: 78 additions & 0 deletions cmd/vroute/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2022 Kendall Tauser
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

package main

import (
"fmt"
"os"
"os/signal"
"syscall"

"github.com/fire833/vroute/pkg/controller"
)

// Unprivileged controllerloop subprocess main function.
func controllerMain() {

fmt.Printf("starting api process, dropping process privilege")

if os.Getuid() != unprivilegedUID || os.Getgid() != unprivilegedGID {
if e := dropPriv(); e != nil {
// TODO send calls to the other processes to kill themselves, and kill the whole control plane.
}
}

fmt.Printf("starting node control process, initializing signal handler")

sig := make(chan os.Signal, 5)
signal.Notify(sig)

for _, controller := range controller.RegisteredControllers {
go controller.BeginWorkers(controller.RunWorkers())
}

// Wait for signals for this process.
controllerSignalHandler(sig)

}

func controllerSignalHandler(sig chan os.Signal) error {
for {
signal := <-sig

switch signal {
case syscall.SIGHUP: // Reload configuration
{

}
case syscall.SIGKILL | syscall.SIGINT: // Hard stop process.
{
break
}
case syscall.SIGTERM: // Gracefully kill the process and all control loops
{
break
}
default:
{
continue // Basically just ignore any other signal.
}
}
}
}
2 changes: 1 addition & 1 deletion cmd/vroute/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
)

// Priviledged node operator process main function.
func node_main() {
func nodeMain() {

fmt.Printf("starting node control process, initializing signal handler")

Expand Down
Loading

0 comments on commit b7aff2e

Please sign in to comment.