Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
c1a3cb6ce5
|
|||
d58226c22c
|
|||
9e1d71d1b2
|
|||
9c70af4f6f
|
|||
7b8cf96b4a
|
|||
7b6e3a9ad6
|
|||
b117739c49
|
|||
b28c47e64d
|
|||
4b14187dad
|
|||
950b1e5e83
|
|||
bf90a10692 | |||
3e7c564a5a
|
12
.github/workflows/macos.yml
vendored
Normal file
12
.github/workflows/macos.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
name: macOS
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: macOS-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: go build
|
23
.github/workflows/ubuntu.yml
vendored
Normal file
23
.github/workflows/ubuntu.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
name: Ubuntu
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: go build
|
||||||
|
|
||||||
|
- name: Install dependencies for tests
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install qemu
|
||||||
|
|
||||||
|
- name: Bootstrap
|
||||||
|
run: ./tools/qemu-debian-img/bootstrap.sh
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: go test -parallel 1 -v ./...
|
34
CHANGELOG.md
34
CHANGELOG.md
@ -4,6 +4,40 @@
|
|||||||
|
|
||||||
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [1.2.1] 2019-12-25
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- macOS support.
|
||||||
|
|
||||||
|
## [1.2.0] 2019-11-15
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Flag for Verbose output. Right now only qemu status messages is
|
||||||
|
implemented.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Kpti settings was not affected for regular runs.
|
||||||
|
|
||||||
|
## [1.1.2] 2019-09-05
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added policykit-1 to rootfs for Ubuntu.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Avoided slow mirrors with use of mirror://mirrors.ubuntu.com for
|
||||||
|
Ubuntu 16.04 and newer.
|
||||||
|
|
||||||
|
## [1.1.1] 2019-08-31
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- macOS support.
|
||||||
|
|
||||||
## [1.1.0] 2019-08-30
|
## [1.1.0] 2019-08-30
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[](https://app.codacy.com/app/jollheef/out-of-tree?utm_source=github.com&utm_medium=referral&utm_content=jollheef/out-of-tree&utm_campaign=Badge_Grade_Dashboard)
|
[](https://app.codacy.com/app/jollheef/out-of-tree?utm_source=github.com&utm_medium=referral&utm_content=jollheef/out-of-tree&utm_campaign=Badge_Grade_Dashboard)
|
||||||
[](https://travis-ci.org/jollheef/out-of-tree)
|
[](https://travis-ci.com/jollheef/out-of-tree)
|
||||||
[](https://goreportcard.com/report/code.dumpstack.io/tools/out-of-tree)
|
[](https://goreportcard.com/report/code.dumpstack.io/tools/out-of-tree)
|
||||||
[](https://out-of-tree.readthedocs.io/en/latest/?badge=latest)
|
[](https://out-of-tree.readthedocs.io/en/latest/?badge=latest)
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=R8W2UQPZ5X5JE&source=url)
|
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=R8W2UQPZ5X5JE&source=url)
|
||||||
|
77
kernel.go
77
kernel.go
@ -15,11 +15,11 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"os/user"
|
"os/user"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/naoina/toml"
|
"github.com/naoina/toml"
|
||||||
"github.com/zcalusic/sysinfo"
|
|
||||||
|
|
||||||
"code.dumpstack.io/tools/out-of-tree/config"
|
"code.dumpstack.io/tools/out-of-tree/config"
|
||||||
)
|
)
|
||||||
@ -100,6 +100,14 @@ func dockerImagePath(sk config.KernelMask) (path string, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func vsyscallAvailable() (available bool, err error) {
|
func vsyscallAvailable() (available bool, err error) {
|
||||||
|
if runtime.GOOS != "linux" {
|
||||||
|
// Docker for non-Linux systems is not using the host
|
||||||
|
// kernel but uses kernel inside a virtual machine, so
|
||||||
|
// it builds by the Docker team with vsyscall support.
|
||||||
|
available = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
buf, err := ioutil.ReadFile("/proc/self/maps")
|
buf, err := ioutil.ReadFile("/proc/self/maps")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -163,6 +171,13 @@ func generateBaseDockerImage(registry string, commands []config.DockerCommand,
|
|||||||
switch sk.DistroType {
|
switch sk.DistroType {
|
||||||
case config.Ubuntu:
|
case config.Ubuntu:
|
||||||
d += "ENV DEBIAN_FRONTEND=noninteractive\n"
|
d += "ENV DEBIAN_FRONTEND=noninteractive\n"
|
||||||
|
if sk.DistroRelease >= "16.04" {
|
||||||
|
from := "http://.*ubuntu/"
|
||||||
|
to := "mirror://mirrors.ubuntu.com/mirrors.txt"
|
||||||
|
file := "/etc/apt/sources.list"
|
||||||
|
s := fmt.Sprintf("sed -i 's;%s;%s;' %s", from, to, file)
|
||||||
|
d += "RUN " + s + "\n"
|
||||||
|
}
|
||||||
d += "RUN apt-get update\n"
|
d += "RUN apt-get update\n"
|
||||||
d += "RUN apt-get install -y build-essential libelf-dev\n"
|
d += "RUN apt-get install -y build-essential libelf-dev\n"
|
||||||
d += "RUN apt-get install -y wget git\n"
|
d += "RUN apt-get install -y wget git\n"
|
||||||
@ -419,66 +434,6 @@ func listDockerImages() (diis []dockerImageInfo, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
|
|
||||||
si := sysinfo.SysInfo{}
|
|
||||||
si.GetSysInfo()
|
|
||||||
|
|
||||||
distroType, err := config.NewDistroType(si.OS.Vendor)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := exec.Command("ls", "/lib/modules")
|
|
||||||
rawOutput, err := cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
log.Println(string(rawOutput), err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
kernelsBase := "/boot/"
|
|
||||||
files, err := ioutil.ReadDir(kernelsBase)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// only for compatibility, docker is not really used
|
|
||||||
dii := dockerImageInfo{
|
|
||||||
ContainerName: config.KernelMask{
|
|
||||||
DistroType: distroType,
|
|
||||||
DistroRelease: si.OS.Version,
|
|
||||||
}.DockerName(),
|
|
||||||
}
|
|
||||||
|
|
||||||
rootfs, err := genRootfsImage(dii, download)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, k := range strings.Fields(string(rawOutput)) {
|
|
||||||
ki := config.KernelInfo{
|
|
||||||
DistroType: distroType,
|
|
||||||
DistroRelease: si.OS.Version,
|
|
||||||
KernelRelease: k,
|
|
||||||
|
|
||||||
KernelSource: "/lib/modules/" + k + "/build",
|
|
||||||
|
|
||||||
KernelPath: kernelsBase + genKernelPath(files, k),
|
|
||||||
InitrdPath: kernelsBase + genInitrdPath(files, k),
|
|
||||||
RootFS: rootfs,
|
|
||||||
}
|
|
||||||
|
|
||||||
vmlinux := "/usr/lib/debug/boot/vmlinux-" + k
|
|
||||||
log.Println("vmlinux", vmlinux)
|
|
||||||
if exists(vmlinux) {
|
|
||||||
ki.VmlinuxPath = vmlinux
|
|
||||||
}
|
|
||||||
|
|
||||||
kcfg.Kernels = append(kcfg.Kernels, ki)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateKernelsCfg(host, download bool) (err error) {
|
func updateKernelsCfg(host, download bool) (err error) {
|
||||||
newkcfg := config.KernelConfig{}
|
newkcfg := config.KernelConfig{}
|
||||||
|
|
||||||
|
77
kernel_linux.go
Normal file
77
kernel_linux.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// Copyright 2018 Mikhail Klementev. All rights reserved.
|
||||||
|
// Use of this source code is governed by a AGPLv3 license
|
||||||
|
// (or later) that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.dumpstack.io/tools/out-of-tree/config"
|
||||||
|
"github.com/zcalusic/sysinfo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
|
||||||
|
si := sysinfo.SysInfo{}
|
||||||
|
si.GetSysInfo()
|
||||||
|
|
||||||
|
distroType, err := config.NewDistroType(si.OS.Vendor)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("ls", "/lib/modules")
|
||||||
|
rawOutput, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(string(rawOutput), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
kernelsBase := "/boot/"
|
||||||
|
files, err := ioutil.ReadDir(kernelsBase)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// only for compatibility, docker is not really used
|
||||||
|
dii := dockerImageInfo{
|
||||||
|
ContainerName: config.KernelMask{
|
||||||
|
DistroType: distroType,
|
||||||
|
DistroRelease: si.OS.Version,
|
||||||
|
}.DockerName(),
|
||||||
|
}
|
||||||
|
|
||||||
|
rootfs, err := genRootfsImage(dii, download)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range strings.Fields(string(rawOutput)) {
|
||||||
|
ki := config.KernelInfo{
|
||||||
|
DistroType: distroType,
|
||||||
|
DistroRelease: si.OS.Version,
|
||||||
|
KernelRelease: k,
|
||||||
|
|
||||||
|
KernelSource: "/lib/modules/" + k + "/build",
|
||||||
|
|
||||||
|
KernelPath: kernelsBase + genKernelPath(files, k),
|
||||||
|
InitrdPath: kernelsBase + genInitrdPath(files, k),
|
||||||
|
RootFS: rootfs,
|
||||||
|
}
|
||||||
|
|
||||||
|
vmlinux := "/usr/lib/debug/boot/vmlinux-" + k
|
||||||
|
log.Println("vmlinux", vmlinux)
|
||||||
|
if exists(vmlinux) {
|
||||||
|
ki.VmlinuxPath = vmlinux
|
||||||
|
}
|
||||||
|
|
||||||
|
kcfg.Kernels = append(kcfg.Kernels, ki)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
18
kernel_macos.go
Normal file
18
kernel_macos.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2018 Mikhail Klementev. All rights reserved.
|
||||||
|
// Use of this source code is governed by a AGPLv3 license
|
||||||
|
// (or later) that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"code.dumpstack.io/tools/out-of-tree/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
|
||||||
|
err = errors.New("generate host kernels for macOS is not supported")
|
||||||
|
return
|
||||||
|
}
|
12
main.go
12
main.go
@ -84,7 +84,7 @@ func main() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
app.Author("Mikhail Klementev <root@dumpstack.io>")
|
app.Author("Mikhail Klementev <root@dumpstack.io>")
|
||||||
app.Version("1.1.0")
|
app.Version("1.2.1")
|
||||||
|
|
||||||
pathFlag := app.Flag("path", "Path to work directory")
|
pathFlag := app.Flag("path", "Path to work directory")
|
||||||
path := pathFlag.Default(".").ExistingDir()
|
path := pathFlag.Default(".").ExistingDir()
|
||||||
@ -155,6 +155,9 @@ func main() {
|
|||||||
pewTagFlag := pewCommand.Flag("tag", "Log tagging")
|
pewTagFlag := pewCommand.Flag("tag", "Log tagging")
|
||||||
pewTag := pewTagFlag.String()
|
pewTag := pewTagFlag.String()
|
||||||
|
|
||||||
|
pewVerboseFlag := pewCommand.Flag("verbose", "Show more information")
|
||||||
|
pewVerbose := pewVerboseFlag.Bool()
|
||||||
|
|
||||||
kernelCommand := app.Command("kernel", "Manipulate kernels")
|
kernelCommand := app.Command("kernel", "Manipulate kernels")
|
||||||
kernelNoDownload := kernelCommand.Flag("no-download",
|
kernelNoDownload := kernelCommand.Flag("no-download",
|
||||||
"Do not download qemu image while kernel generation").Bool()
|
"Do not download qemu image while kernel generation").Bool()
|
||||||
@ -264,6 +267,10 @@ func main() {
|
|||||||
log.Fatalln("Only one of disable/enable can be used at once")
|
log.Fatalln("Only one of disable/enable can be used at once")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *yekpti && *nokpti {
|
||||||
|
log.Fatalln("Only one of disable/enable can be used at once")
|
||||||
|
}
|
||||||
|
|
||||||
kcfg, err := config.ReadKernelConfig(*kcfgPath)
|
kcfg, err := config.ReadKernelConfig(*kcfgPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
@ -299,7 +306,8 @@ func main() {
|
|||||||
case pewCommand.FullCommand():
|
case pewCommand.FullCommand():
|
||||||
err = pewHandler(kcfg, *path, *pewKernel, *pewBinary,
|
err = pewHandler(kcfg, *path, *pewKernel, *pewBinary,
|
||||||
*pewTest, *pewGuess, stop, *qemuTimeout, *dockerTimeout,
|
*pewTest, *pewGuess, stop, *qemuTimeout, *dockerTimeout,
|
||||||
*pewMax, *pewRuns, *pewDist, *pewTag, *pewThreads, db)
|
*pewMax, *pewRuns, *pewDist, *pewTag, *pewThreads,
|
||||||
|
db, *pewVerbose)
|
||||||
case kernelListCommand.FullCommand():
|
case kernelListCommand.FullCommand():
|
||||||
err = kernelListHandler(kcfg)
|
err = kernelListHandler(kcfg)
|
||||||
case kernelAutogenCommand.FullCommand():
|
case kernelAutogenCommand.FullCommand():
|
||||||
|
3
pack.go
3
pack.go
@ -51,7 +51,8 @@ func packHandler(db *sql.DB, path, registry string, stop time.Time,
|
|||||||
|
|
||||||
pewHandler(kcfg, workPath, "", "", "", false,
|
pewHandler(kcfg, workPath, "", "", "", false,
|
||||||
stop, dockerTimeout, qemuTimeout,
|
stop, dockerTimeout, qemuTimeout,
|
||||||
kernelRuns, exploitRuns, pathDevNull, tag, threads, db)
|
kernelRuns, exploitRuns, pathDevNull,
|
||||||
|
tag, threads, db, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
23
pew.go
23
pew.go
@ -303,7 +303,7 @@ func copyTest(q *qemu.System, testPath string, ka config.Artifact) (
|
|||||||
func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
||||||
ki config.KernelInfo, binaryPath, testPath string,
|
ki config.KernelInfo, binaryPath, testPath string,
|
||||||
qemuTimeout, dockerTimeout time.Duration, dist, tag string,
|
qemuTimeout, dockerTimeout time.Duration, dist, tag string,
|
||||||
db *sql.DB) {
|
db *sql.DB, verbose bool) {
|
||||||
|
|
||||||
defer swg.Done()
|
defer swg.Done()
|
||||||
|
|
||||||
@ -328,6 +328,7 @@ func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
|||||||
q.SetKASLR(!ka.Mitigations.DisableKaslr)
|
q.SetKASLR(!ka.Mitigations.DisableKaslr)
|
||||||
q.SetSMEP(!ka.Mitigations.DisableSmep)
|
q.SetSMEP(!ka.Mitigations.DisableSmep)
|
||||||
q.SetSMAP(!ka.Mitigations.DisableSmap)
|
q.SetSMAP(!ka.Mitigations.DisableSmap)
|
||||||
|
q.SetKPTI(!ka.Mitigations.DisableKpti)
|
||||||
|
|
||||||
err = q.Start()
|
err = q.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -336,6 +337,18 @@ func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
|||||||
}
|
}
|
||||||
defer q.Stop()
|
defer q.Stop()
|
||||||
|
|
||||||
|
if verbose {
|
||||||
|
go func() {
|
||||||
|
for !q.Died {
|
||||||
|
time.Sleep(time.Minute)
|
||||||
|
log.Println(ka.Name, ki.DistroType,
|
||||||
|
ki.DistroRelease, ki.KernelRelease,
|
||||||
|
"still alive")
|
||||||
|
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
usr, err := user.Current()
|
usr, err := user.Current()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -394,7 +407,7 @@ func performCI(ka config.Artifact, kcfg config.KernelConfig, binaryPath,
|
|||||||
testPath string, stop time.Time,
|
testPath string, stop time.Time,
|
||||||
qemuTimeout, dockerTimeout time.Duration,
|
qemuTimeout, dockerTimeout time.Duration,
|
||||||
max, runs int64, dist, tag string, threads int,
|
max, runs int64, dist, tag string, threads int,
|
||||||
db *sql.DB) (err error) {
|
db *sql.DB, verbose bool) (err error) {
|
||||||
|
|
||||||
found := false
|
found := false
|
||||||
|
|
||||||
@ -420,7 +433,7 @@ func performCI(ka config.Artifact, kcfg config.KernelConfig, binaryPath,
|
|||||||
swg.Add()
|
swg.Add()
|
||||||
go whatever(&swg, ka, kernel, binaryPath,
|
go whatever(&swg, ka, kernel, binaryPath,
|
||||||
testPath, qemuTimeout, dockerTimeout,
|
testPath, qemuTimeout, dockerTimeout,
|
||||||
dist, tag, db)
|
dist, tag, db, verbose)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -477,7 +490,7 @@ func pewHandler(kcfg config.KernelConfig,
|
|||||||
workPath, ovrrdKrnl, binary, test string, guess bool,
|
workPath, ovrrdKrnl, binary, test string, guess bool,
|
||||||
stop time.Time, qemuTimeout, dockerTimeout time.Duration,
|
stop time.Time, qemuTimeout, dockerTimeout time.Duration,
|
||||||
max, runs int64, dist, tag string, threads int,
|
max, runs int64, dist, tag string, threads int,
|
||||||
db *sql.DB) (err error) {
|
db *sql.DB, verbose bool) (err error) {
|
||||||
|
|
||||||
ka, err := config.ReadArtifactConfig(workPath + "/.out-of-tree.toml")
|
ka, err := config.ReadArtifactConfig(workPath + "/.out-of-tree.toml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -507,7 +520,7 @@ func pewHandler(kcfg config.KernelConfig,
|
|||||||
|
|
||||||
err = performCI(ka, kcfg, binary, test,
|
err = performCI(ka, kcfg, binary, test,
|
||||||
stop, qemuTimeout, dockerTimeout,
|
stop, qemuTimeout, dockerTimeout,
|
||||||
max, runs, dist, tag, threads, db)
|
max, runs, dist, tag, threads, db, verbose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,8 @@ ENV RELEASE=trusty
|
|||||||
RUN mkdir $IMAGEDIR
|
RUN mkdir $IMAGEDIR
|
||||||
|
|
||||||
# Must be executed with --privileged because of /dev/loop
|
# Must be executed with --privileged because of /dev/loop
|
||||||
CMD debootstrap --include=openssh-server $RELEASE $TMPDIR $REPOSITORY && \
|
CMD debootstrap --include=openssh-server,policykit-1 \
|
||||||
|
$RELEASE $TMPDIR $REPOSITORY && \
|
||||||
/shared/setup.sh $TMPDIR && \
|
/shared/setup.sh $TMPDIR && \
|
||||||
qemu-img create $IMAGE 2G && \
|
qemu-img create $IMAGE 2G && \
|
||||||
mkfs.ext4 -F $IMAGE && \
|
mkfs.ext4 -F $IMAGE && \
|
||||||
|
@ -26,7 +26,8 @@ ENV RELEASE=bionic
|
|||||||
RUN mkdir $IMAGEDIR
|
RUN mkdir $IMAGEDIR
|
||||||
|
|
||||||
# Must be executed with --privileged because of /dev/loop
|
# Must be executed with --privileged because of /dev/loop
|
||||||
CMD debootstrap --include=openssh-server $RELEASE $TMPDIR $REPOSITORY && \
|
CMD debootstrap --include=openssh-server,policykit-1 \
|
||||||
|
$RELEASE $TMPDIR $REPOSITORY && \
|
||||||
/shared/setup.sh $TMPDIR && \
|
/shared/setup.sh $TMPDIR && \
|
||||||
qemu-img create $IMAGE 2G && \
|
qemu-img create $IMAGE 2G && \
|
||||||
mkfs.ext4 -F $IMAGE && \
|
mkfs.ext4 -F $IMAGE && \
|
||||||
|
Reference in New Issue
Block a user