Skip to content

Commit

Permalink
Merge pull request #3 from hashicorp/dev
Browse files Browse the repository at this point in the history
Merging in 0.1.3 from Dev
  • Loading branch information
Christian Frichot authored Nov 12, 2020
2 parents 1f0d592 + 2190038 commit bea993b
Show file tree
Hide file tree
Showing 12 changed files with 634 additions and 114 deletions.
12 changes: 5 additions & 7 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ parameters:
default: "vault_selinux"
hc-version:
type: string
default: "0.1.1"
default: "0.1.3"
hc-package-iteration:
type: string
default: "1"

references:
docker-images:
artifactory: &ARTIFACTORY_DOCKER_IMAGE productdelivery-docker-release-local.artifactory.hashicorp.engineering/artifactory-repo-tool:0.1.16
fedora: &FEDORA_DOCKER_IMAGE "fedora@sha256:ee55117b3058f2f12961184fae4b9c392586e400487626c6bd0d15b4eae94ecc"
ubuntu: &UBUNTU_DOCKER_IMAGE "circleci/buildpack-deps:bionic"
fedora: &FEDORA_DOCKER_IMAGE "docker.mirror.hashicorp.services/fedora@sha256:ee55117b3058f2f12961184fae4b9c392586e400487626c6bd0d15b4eae94ecc"
ubuntu: &UBUNTU_DOCKER_IMAGE "docker.mirror.hashicorp.services/circleci/buildpack-deps:bionic"
centos: &CENTOS_DOCKER_IMAGE "docker.mirror.hashicorp.services/centos:8"

environment: &ENVIRONMENT
Expand All @@ -39,7 +38,6 @@ jobs:
steps:
- checkout
# The below is required because I'm building on a generic CentOS and Fedora container
# Ideally this would use the ARTIFACTORY_DOCKER_IMAGE and the pre-reqs would exist
- when:
condition:
equal: [ << parameters.host-image >>, *FEDORA_DOCKER_IMAGE ]
Expand Down Expand Up @@ -90,8 +88,8 @@ workflows:
- package:
matrix:
parameters:
# host-image: [*FEDORA_DOCKER_IMAGE, *CENTOS_DOCKER_IMAGE]
host-image: [*CENTOS_DOCKER_IMAGE]
host-image: [*FEDORA_DOCKER_IMAGE, *CENTOS_DOCKER_IMAGE]
# host-image: [*CENTOS_DOCKER_IMAGE]
# filters:
# branches:
# only: dev
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
**/plan.out
**/terraform.tfstate*
**/.terraform*
**/*.rpm
143 changes: 107 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,124 @@
# vault-selinux-policies

**NOT READY FOR USE AS OF 23-Sept-2020**
A set of base SELinux policies, and CircleCI scripts to package the policies into RPMs (targeting CentOS and Fedora) for [HashiCorp Vault](https://www.vaultproject.io).

A set of base SELinux policies, and CircleCI to _try_ and package the policies into RPMs for Vault currently under development.
It is _not_ recommended to run these in Production without extensive testing first!

## Overview

This repo intends to be a draft setup for holding the raw SELinux policies files, the packaging scripts _and_ validation scripts to package and validate via CircleCI. This repo mirrors the patterns from https://github.com/hashicorp/linux-packaging.
This repo holds the raw SELinux policy files, the packaging scripts _and_ validation scripts to package and validate via CircleCI.

### Caveats

* The SELinux policy file contexts, used as part of SELinux labelling, map to where the packaged versions of Vault install their config, data and log files. The Vault packages are available from: https://learn.hashicorp.com/tutorials/vault/getting-started-install
* The SELinux policies do allow fairly open outbound network traffic, although not outbound HTTP access by default.
* The SELinux policies haven't been tested with Vault+Consul, or other storage engines, except for Integrated Storage.
* The current policy is in Enforced Mode (which will block and audit), but can be edited into Permissive Mode (which will audit only).

### Layout

In the [products/vault_selinux/](products/vault_selinux/) folder exists the raw SELinux config files, plus [package.sh](products/vault_selinux/package.sh). This script gets executed by [circle](.circleci/config.yml).
The [products/vault_selinux/](products/vault_selinux/) folder contains the raw SELinux config files, plus [package.sh](products/vault_selinux/package.sh). This script gets executed by [circle](.circleci/config.yml).

The [products/vault_selinux/](products/vault_selinux/) folder contains the [ci/validate.sh](products/vault_selinux/ci/validate.sh) script. This gets executed by [circle](.circleci/config.yml) too.

### Booleans

While the current baseline provides fairly open access, there are some features that are gated by SELinux [Booleans](https://wiki.gentoo.org/wiki/SELinux/Tutorials/Using_SELinux_booleans).

* `vault_outbound_udp_dns` - if set will allow Vault to query DNS via UDP
* `vault_outbound_http` - if set will allow Vault to send outbound HTTP requests

In the [products/vault_selinux/](products/vault_selinux/) folder exists the [ci/validate.sh](products/vault_selinux/ci/validate.sh) script. This gets executed by [circle](.circleci/config.yml) too.
To enable the booleans:

```
sudo setsebool vault_outbound_udp_dns on
sudo setsebool vault_outbound_http on
```

If you'd like to persist these setting:

```
sudo setsebool -P vault_outbound_udp_dns on
sudo setsebool -P vault_outbound_http on
```

## Editing the source

To edit the underlying SELinux policies, edit the `vault*` files in [products/vault_selinux/](products/vault_selinux/).

The file context mappings are in `vault.fc` - the interfaces are in `vault.if` and the main policy is in `vault.te`.

The `vault.sh` is used to deploy and bundle the policy into an rpm file. This is the main way to update the policy on the system, and was generated with a `sepolicy generate --init -n vault /usr/sbin/vault`
The `vault.sh` is used to compile, install and bundle the policy into an RPM file. This is the main way to update the policy on the system, and was generated with `sepolicy generate --init -n vault /usr/sbin/vault`

The `vault_selinux.spec` is also generated by the above, and is used to create the RPM. Although this file has been modified.

## Updating the rpm
## CI

Pushing to the main branch of this repo will execute CircleCI jobs: https://app.circleci.com/pipelines/github/hashicorp/vault-selinux-policies

These jobs will save RPM artifacts in the package steps, one for CentOS, and one for Fedora.

## Testing locally

This has only been tested on CentOS and Fedora, and requires some pre-requisites. The AWS steps below offer a more thorough example of how to test this on CentOS and Fedora.

### CentOS

Install Vault:

```
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install vault
```

Install SELinux Policy development pre-requisites:

Pushing this repo to master will kick off the CI job: https://app.circleci.com/pipelines/github/hashicorp/vault-selinux-policies?branch=master
```
sudo yum -y install policycoreutils-devel setools-console rpm-build selinux-policy-devel selinux-policy-targeted
```

Clone this repo, update versions, then run the `vault.sh` script.

```
cd products/vault_selinux
sed -i "s^#VERSION#^0.1.1^g" vault.te
sed -i "s^#VERSION#^0.1.1^g" vault_selinux.spec
sudo ./vault.sh
```

## Setting up test instances
To re-install, after making changes to the SELinux files, you can re-run this script.

To test that the RPM packages are installable the `terraform` directory contains logic to spin up 2 instances:
- A Fedora EC2 instance
- A CentOS EC2 instance
### Fedora

Install Vault:

```
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
sudo dnf -y install vault
```

Install SELinux Policy development pre-requisites:

```
sudo dnf -y install policycoreutils-devel setools-console rpm-build
```

Clone this repo, update versions, then run the `vault.sh` script.

```
cd products/vault_selinux
sed -i "s^#VERSION#^0.1.1^g" vault.te
sed -i "s^#VERSION#^0.1.1^g" vault_selinux.spec
sudo ./vault.sh
```

To re-install, after making changes to the SELinux files, you can re-run this script.

## Testing on AWS

To test that the RPM packages are installable the `terraform` directory contains logic to spin up 2 Centos instances.

```
cd terraform
Expand All @@ -45,21 +131,17 @@ SSH to the instances then run:
sudo cloud-init status --wait
```

Wait until the cloud-init stuff has finished

Install Vault as per instructions from: https://learn.hashicorp.com/tutorials/vault/getting-started-install?in=vault/getting-started following the Linux `CentOS/RHEL` or `Fedora` commands

Then scp `vault_selinux-1.1-1.el7.noarch.rpm` to the instances from this folder.
Wait until the cloud-init stuff has finished, this will install Vault from the latest available package.

Currently, the rpm is being built in CircleCI [here](https://app.circleci.com/pipelines/github/hashicorp/vault-selinux-policies?branch=master), and saved as an artifact in the package step.
SCP the appropriate RPM to the instances.

Then from the instances (or dnf/yum install):
Then from the instances (or dnf/yum install), for example:

```
sudo rpm -ivh vault_selinux-1.1-1.el7.noarch.rpm
```

You can check that the policy has applied properly by checking appropriate vault_t contexts in:
You can check that the policy has applied properly by checking appropriate `vault_t` contexts in:

```
ls -alZ /opt/vault
Expand Down Expand Up @@ -105,23 +187,12 @@ Don't forget to tear down your infra after:
make down
```

From the terraform folder.
from the terraform folder.

# References blogs etc
## End to End Testing on AWS

I did a _lot_ of googling to get my head around this, and realize I have a bunch of tabs open, so I'll try and capture my open tabs here:
First, ensure you can `make up` and `make down` as above.

* Red Hat's What Is SELinux https://www.redhat.com/en/topics/linux/what-is-selinux
* Sysadmin's guide to selinux https://opensource.com/article/18/7/sysadmin-guide-selinux
* How to generate a new initial policy using sepolicy-generate https://mgrepl.wordpress.com/2015/05/20/how-to-create-a-new-initial-policy-using-sepolicy-generate-tool/
* Fun with selinux presentation: https://mgrepl.fedorapeople.org/PolicyCourse/writingSELinuxpolicy_MUNI.pdf
* Selinux labels: https://wiki.gentoo.org/wiki/SELinux/Labels
* Using sesearch https://www.server-world.info/en/note?os=CentOS_7&p=selinux&f=11
* Basic policy editing examples https://www.linuxtopia.org/online_books/writing_SELinux_policy_guide/policy_editing_examples_12.html
* Customizing selinux policies https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/deployment_guide/sec-sel-policy-customizing
* Adjusting selinux policies https://download.geo.drweb.com/pub/drweb/unix/doc/HTML/ControlCenter/en/dw_8_install_selinux.htm
* I cloned the following two repos to find what certain interfaces, macros and methods did. https://github.com/SELinuxProject/refpolicy & https://github.com/fedora-selinux/selinux-policy
* Troubleshooting selinux problems https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/using_selinux/troubleshooting-problems-related-to-selinux_using-selinux
* Linux restorecon command examples https://www.thegeekstuff.com/2017/05/restorecon-examples/
* Walk through of the INN policy https://www.linuxtopia.org/online_books/writing_SELinux_policy_guide/case_study_13.html
Second, place a copy of the CentOS RPM into the `terraform` folder as `vault_selinux.rpm`.

Then run `make integration` from within the `terraform` folder. This will spin up the cluster, as above, then interact with the instances, deploying the RPM, and ensuring that they can function.
7 changes: 4 additions & 3 deletions products/vault_selinux/ci/validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,22 @@ docker exec $CENTOS_ID yum install -y /app/$(ls products/*/*el8.noarch.rpm)

docker exec $CENTOS_ID bash -c 'semanage module -l | grep vault'
docker exec $CENTOS_ID bash -c 'semanage port -l | grep vault_cluster_port_t'
docker exec $CENTOS_ID bash -c 'semanage boolean -l | grep vault_outbound'
docker exec $CENTOS_ID yum remove -y vault_selinux

docker stop $CENTOS_ID

# Run Fedora rpm validation
FEDORA_ID=$(docker run -d -v $WORKDIR:/app -e HC_PRODUCT=$HC_PRODUCT -e HC_VERSION=$HC_VERSION \
--entrypoint="" -w="/app" --privileged $IMAGE_RPM_SYSTEM /usr/sbin/init)
# Wait for CentOS to spin up
# Wait for Fedora to spin up
sleep 1
docker exec $FEDORA_ID dnf install -y libselinux-utils policycoreutils policycoreutils-python-utils selinux-policy-targeted
# docker exec $FEDORA_ID dnf install -y /app/$(ls products/*/*fc31.noarch.rpm)
docker exec $FEDORA_ID dnf install -y /app/$(ls products/*/*.noarch.rpm)
docker exec $FEDORA_ID dnf install -y /app/$(ls products/*/*fc31.noarch.rpm)

docker exec $FEDORA_ID bash -c 'semanage module -l | grep vault'
docker exec $FEDORA_ID bash -c 'semanage port -l | grep vault_cluster_port_t'
docker exec $FEDORA_ID bash -c 'semanage boolean -l | grep vault_outbound'
docker exec $FEDORA_ID dnf remove -y vault_selinux

docker stop $FEDORA_ID
Expand Down
8 changes: 4 additions & 4 deletions products/vault_selinux/vault.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ make -f /usr/share/selinux/devel/Makefile vault.pp || exit
# Generate a man page off the installed module
sepolicy manpage -p . -d vault_t
# Fixing the file context on /usr/sbin/vault
/sbin/restorecon -F -R -v /usr/bin/vault
/sbin/restorecon -F -R -v -i /usr/bin/vault
# Fixing the file context on /var/log/vault
/sbin/restorecon -F -R -v /var/log/vault
/sbin/restorecon -F -R -v -i /var/log/vault
# Fixing the file context on /opt/vault
/sbin/restorecon -F -R -v /opt/vault
/sbin/restorecon -F -R -v -i /opt/vault
# Fixing the file context on /etc/vault.d
/sbin/restorecon -F -R -v /etc/vault.d
/sbin/restorecon -F -R -v -i /etc/vault.d
# Labeling 8201
/sbin/semanage port -a -t vault_cluster_port_t -p tcp 8201
# Generate a rpm package for the newly generated policy
Expand Down
31 changes: 31 additions & 0 deletions products/vault_selinux/vault.te
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,34 @@ allow vault_t vault_sys_content_t:file { create getattr lock map open read write
# Need to access log files
allow vault_t vault_log_t:dir { getattr search write add_name };
allow vault_t vault_log_t:file { create append open setattr };

## <desc>
## <p>
## Allow vault servers to send outbound DNS
## typically used to resolve DNS.
## </p>
## </desc>
gen_tunable(vault_outbound_udp_dns, false)
tunable_policy(`vault_outbound_udp_dns',`
require {
class udp_socket { connect create getattr read setopt write };
type vault_t;
}
allow vault_t self:udp_socket { connect create getattr read setopt write };
sysnet_read_config(vault_t)
')

## <desc>
## <p>
## Allow vault servers to connect
## to external HTTP servers.
## </p>
## </desc>
gen_tunable(vault_outbound_http, false)
tunable_policy(`vault_outbound_http',`
require {
type vault_t;
}
corenet_tcp_connect_http_port(vault_t)
miscfiles_read_generic_certs(vault_t)
')
3 changes: 3 additions & 0 deletions products/vault_selinux/vault_selinux.spec
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ exit 0


%changelog
* Thu Nov 12 2020 Christian Frichot <[email protected]> 0.1.3-1
- Added booleans for outbound udp/dns and http

* Wed Sep 2 2020 Christian Frichot <[email protected]> 0.1.2-1
- Update for Hashicorp RPM Vault install

Expand Down
11 changes: 11 additions & 0 deletions terraform/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ clean: ## Remove .terraform folder, state and plan files
rm plan.out
rm terraform.tfstate*

.PHONY: integration
integration: ## Runs up, then the e2e script
ifeq (,$(wildcard ./vault_selinux.rpm))
@echo "Couldn't find ./vault_selinux.rpm"
@exit 1
endif
make up
./e2e.sh --rpm-file ./vault_selinux.rpm
make down


.PHONY: help
help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
6 changes: 3 additions & 3 deletions terraform/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# quick ec2

A quick/nasty terraform to spin up a separate VPC with public-subnet and an Ubuntu 18.04 server in it. Plus a bit of bootstrapping stuff too.
A quick terraform to spin up instances in aws to test Vault SELinux policies on.

By default this will spin up a CentOS and Fedora instance.

## Prerequisites

Expand All @@ -12,8 +14,6 @@ Oh, and terraform (tested with version 0.12.21).

## Config

Edit `user-data.sh` to your hearts desire.

If you want to modify the 'name' or 'ssh pub key' for terraform feel free to set variables for `name` and `pub_key_file` in setup.auto.tfvars.

Variables:
Expand Down
Loading

0 comments on commit bea993b

Please sign in to comment.