- 아키텍처 설계: OpenLDAP과 Kerberos V를 연동한 클러스터의 아키텍처
- 다운로드 및 설치: 프로젝트 실습을 하기 위한 소프트웨어 설치
- Ansible을 이용한 클러스터 자동 구축 방법: 간단하게 프로젝트 테스트 방법
- 직접 클러스터를 구축하는 방법
OpenLDAP을 활용하여 구축하는 방법은 여러 가지가 있다.
provider 와 consumer 로 역할을 나눈다. provider는 consumer에게 디렉터리 정보들을 전달한다. consumer는 provider가 전달한 수정사항을 반영한다.
consumer는 다른 consumer에게 복제 정보들을 전파할 수 있다. LDAP 서버로 구축하지 않고 LDAP 클라이언트가 consumer 역할을 맡을 수도 있다.
LDAP 클러스터를 MirrorMode로 구성한다.
- Single Master: 기본 설정
- Multiple Master
- 장점: single-master의 단일 장애점 해결. 고가용성.
- 단점: 로드밸런싱 기능 없음. single-master 보다 성능이 좋지 않음.
- MirrorMode
- 장점: 고가용성. Hot-Standby 혹은 Active-Active.
- 단점: 로드밸런싱 기능 필요.
- Syncrepl Proxy Mode: Consumer가 직접 Provider에 접근할 수 없을 때 사용
- Syncrepl: 객체 기반 복제
- refreshOnly: 폴링
- refreshAndPersist: 리스닝
- Delta-syncrepl: 변경로그 기반 복제
- MirrorMode
- 장점: 고가용성. Hot-Standby 혹은 Active-Active.
- 단점: 로드밸런싱 기능 필요.
- Delta-syncrepl: 변경로그 기반 복제
- TLS
- SASL GSSAPI
- Kerberos V
Vagrant와 VirtualBox, Ansible을 사용하여 로컬 환경에 가상머신 클러스터를 구축한다.
vagrant up
명령을 실행하면 VM이 프로비저닝 된다.
PLAY RECAP *********************************************************************
client : ok=11 changed=8 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0
kdc1 : ok=27 changed=21 unreachable=0 failed=0 skipped=5 rescued=0 ignored=0
kdc2 : ok=15 changed=10 unreachable=0 failed=0 skipped=10 rescued=0 ignored=0
ldap1 : ok=34 changed=28 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
ldap2 : ok=33 changed=27 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
vagrant ssh client
명령으로 Client 머신에 접속한다.
Client 테스트부터 시작한다.
다음은 Ansible을 사용하지 않고 직접 클러스터를 구축하는 방법이다.
- 공통 도메인(REALM)은
EXAMPLE.COM
으로 설정한다. - IP는
192.168.X.X
대역으로 설정한다.
Role | Domain | IP |
---|---|---|
Provider | ldap1.example.com | 192.168.9.101 |
Provider | ldap2.example.com | 192.168.9.102 |
KDC | kdc1.example.com | 192.168.9.103 |
KDC | kdc2.example.com | 192.168.9.104 |
Client | client.example.com | 192.168.9.105 |
Vagrantfile을 준비한다.
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "centos/7"
(1..2).each do |i|
config.vm.define vm_name = "ldap#{i}" do |config|
config.vm.hostname = "ldap#{i}"
config.vm.network :private_network, ip: "192.168.9.#{i+100}"
end
end
(1..2).each do |i|
config.vm.define vm_name = "kdc#{i}" do |config|
config.vm.hostname = "kdc#{i}"
config.vm.network :private_network, ip: "192.168.9.#{i+102}"
end
end
config.vm.define vm_name = "client" do |config|
config.vm.hostname = "client"
config.vm.network :private_network, ip: "192.168.9.105"
end
end
VM을 시작한다.
vagrant up
서버에 접속한다.
vagrant ssh ldap1 # ldap 1
vagrant ssh ldap2 # ldap 2
vagrant ssh kdc1 # kdc 1
vagrant ssh kdc2 # kdc 2
vagrant ssh client # client
LDAP 설정 과정은 root 권한으로 설정한다.
sudo -Es
각 서버 /etc/hosts
마다 전체 주소 도메인 네임(FQDN)을 등록한다. FQDN이 LDAP 설정값과 일치하지 않으면 LDAP 서버를 실행할 수 없다.
예를 들어, ldap1 서버에서 /etc/hosts
를 고친다.
192.168.9.101 ldap1.example.com ldap1
192.168.9.102 ldap2.example.com ldap2
192.168.9.103 kdc1.example.com kdc1
192.168.9.104 kdc2.example.com kdc2
192.168.9.105 client.example.com client
호스트 네임을 확인한다.
# 호스트 네임 확인 명령
hostname # ldap1
hostname -f # ldap1.example.com
# 호스트 네임 변경 명령
hostnamectl set-hostname ldap1
나머지 서버들도 /etc/hosts
를 설정한다.
미리 만들어 둔 SSH Key를 설정한다.
mkdir -m 700 /root/.ssh
cp /vagrant/insecure/id_rsa.pub /root/.ssh
cp /vagrant/insecure/id_rsa /root/.ssh
cp /vagrant/insecure/authorized_keys /root/.ssh
chmod 644 /root/.ssh/id_rsa.pub
chmod 600 /root/.ssh/id_rsa /root/.ssh/authorized_keys
LDAP 1, LDAP 2 호스트에 필요한 패키지를 설치한다.
- OpenLDAP 라이브러리, 서버, 클라이언트
- SASL 라이브러리
yum install -y openldap openldap-servers openldap-clients
yum install -y cyrus-sasl cyrus-sasl-gssapi cyrus-sasl-ldap cyrus-sasl-md5 cyrus-sasl-plain
패키지에 자동으로 설정된 slapd 설정을 제거한다.
rm -rf /etc/openldap/slapd.d
mkdir /etc/openldap/slapd.d
slapd가 사용할 데이터베이스 저장 경로를 생성한다.
mkdir /var/lib/ldap/data /var/lib/ldap/accesslog
chown ldap:ldap /var/lib/ldap/data /var/lib/ldap/accesslog
slapd 데이터베이스 저장 경로의 SELinux 보안 정보를 확인한다.
ls -ldZ /var/lib/ldap
# drwx------. ldap ldap system_u:object_r:slapd_db_t:s0 /var/lib/ldap
slapd 로그 디렉터리를 생성한다.
mkdir /var/log/slapd
slapd의 로그를 수집한다.
cat > /etc/rsyslog.d/slapd.conf << \EOF
$template slapdtmpl,"[%$DAY%-%$MONTH%-%$YEAR% %timegenerated:12:19:date-rfc3339%] %app-name% %syslogseverity-text% %msg%\n"
local4.* /var/log/slapd/slapd.log;slapdtmpl
EOF
rsyslog를 재시작한다.
systemctl restart rsyslog
rsyslog가 생성한 로그를 백업한다.
cat > /etc/logrotate.d/slapd << EOF
/var/log/slapd/slapd.log {
compress
copytruncate
create 0600 root root
daily
dateext
notifempty
maxage 31
missingok
rotate 31
}
EOF
logrotate를 강제 실행한다.
/usr/sbin/logrotate -f /etc/logrotate.conf
홈 디렉터리로 이동한다.
cd ~
개인키 생성
openssl genrsa -out rootca.key
인증요청서 정보 작성
cat > rootca.csr.conf << EOF
[ req ]
default_bits = 2048
default_md = sha256
distinguished_name = req_distinguished_name
prompt = no
encrypt_key = no
[ req_distinguished_name ]
countryName = "KR"
stateOrProvinceName = "Seoul"
localityName = "Seoul"
0.organizationName = "MyCompany"
organizationalUnitName = "TopUnit"
commonName = "RootCA"
EOF
인증요청서 생성
openssl req -new -key rootca.key -config rootca.csr.conf -out rootca.csr
RootCA 인증서 생성
openssl req -x509 -sha256 -nodes -days 364 -key rootca.key -in rootca.csr -out rootca.crt
개인키 생성
openssl genrsa -out example.com.key
인증요청서 정보 작성
cat > example.com.csr.conf << EOF
[ req ]
default_bits = 2048
default_md = sha256
distinguished_name = req_distinguished_name
prompt = no
encrypt_key = no
[ req_distinguished_name ]
countryName = "KR"
stateOrProvinceName = "Seoul"
localityName = "Seoul"
0.organizationName = "MyCompany"
organizationalUnitName = "MyUnit"
commonName = "*.example.com"
EOF
인증요청서 생성
openssl req -new -key example.com.key -config example.com.csr.conf -out example.com.csr
서버 인증서 생성
openssl x509 -req -in example.com.csr -CAcreateserial -CA rootca.crt -CAkey rootca.key -out example.com.crt
개인키 생성
openssl genrsa -out replicator.key
인증요청서 정보 작성
cat > replicator.csr.conf << EOF
[ req ]
default_bits = 2048
default_md = sha256
distinguished_name = req_distinguished_name
prompt = no
encrypt_key = no
[ req_distinguished_name ]
countryName = "KR"
stateOrProvinceName = "Seoul"
localityName = "Seoul"
0.organizationName = "MyCompany"
organizationalUnitName = "MyUnit"
commonName = "replicator"
EOF
인증요청서 생성
openssl req -new -key replicator.key -config replicator.csr.conf -out replicator.csr
서버 인증서 생성
openssl x509 -req -in replicator.csr -CAcreateserial -CA rootca.crt -CAkey rootca.key -out replicator.crt
rootca.crt
,rootca.csr
,rootca.csr.conf
,rootca.key
,rootca.srl
example.com.crt
,example.com.csr
,example.com.csr.conf
,example.com.key
replicator.crt
,replicator.csr
,replicator.csr.conf
,replicator.key
LDAP 서버마다 /etc/openldap/certs/
경로에 rootca.crt
, example.com.crt
, example.com.key
, replicator.crt
, replicator.key
를 복제한다.
기존 파일 삭제
rm -f /etc/openldap/certs/*
인증서 파일 저장
cp ./{rootca.crt,example.com.crt,example.com.key,replicator.crt,replicator.key} /etc/openldap/certs/
key 파일 권한 수정
chmod 440 /etc/openldap/certs/{example.com.key,replicator.key}
chgrp ldap /etc/openldap/certs/{example.com.key,replicator.key}
CentOS 클라이언트 설정 파일: /etc/openldap/ldap.conf
Self Signed Certificate를 사용한 경우, LDAP 클라이언트로 접속할 때 ldap_start_tls: Connect error (-11)
에러가 발생한다. 다음 중 한가지 방법으로 클라이언트 접속을 설정해야 한다.
/etc/openldap/ldap.conf
: TLS_CACERT
TLS_CACERT /etc/openldap/certs/rootca.crt
/etc/openldap/ldap.conf
: TLS_REQCERT
TLS_REQCERT의 기본값은 demand다. allow로 변경한다.
TLS_REQCERT allow
~/.ldaprc
: TLS_REQCERT
사용자마다 다른 보안 설정이 가능하다.
TLS_REQCERT allow
Python으로 LDAP 관리자 비밀번호를 생성한다. 다음 방법 중 한 가지로 비밀번호를 생성한다. 생성한 비밀번호는 기록한다.
생성 비밀번호: {CRYPT}$5$Wj1kVTXmyH/LwLip$i4GZ5vy.CaLski1Sp78MTqMgCqmEb37IX6SqOxWiIb2
pip2 install passlib
python2 -c 'import sys; from passlib.hash import sha256_crypt; print("{CRYPT}" + sha256_crypt.using(rounds=5000).hash(sys.argv[1]))' 'password'
pip3 install passlib
python3 -c 'import sys; from passlib.hash import sha256_crypt; print("{CRYPT}" + sha256_crypt.using(rounds=5000).hash(sys.argv[1]))' 'password'
rounds
값이 5000일 때, rounds
는 생략된다.
python -c 'import sys, crypt; print("{CRYPT}" + crypt.crypt(sys.argv[1], crypt.mksalt(crypt.METHOD_SHA256)))' "password"
- 서버 설정 LDIF: ldap1.ldif
- 관리자 비밀번호를 olcRootPW의 값으로 넣는다.
- 기본 디렉터리 정보 설정 LDIF: directories.ldif
slapadd -v -F /etc/openldap/slapd.d -n 0 -l ldap1.ldif
chown -R ldap:ldap /etc/openldap/slapd.d
systemctl start slapd
systemctl enable slapd
ldapadd -x -w password -D "cn=manager,ou=admins,dc=example,dc=com" -f directories.ldif -Z
- 서버 설정 LDIF: ldap2.ldif
- 관리자 비밀번호를 olcRootPW의 값으로 넣는다.
slapadd -v -F /etc/openldap/slapd.d -n 0 -l ldap1.ldif
chown -R ldap:ldap /etc/openldap/slapd.d
systemctl start slapd
systemctl enable slapd
ldapsearch -x -w password -H ldap://ldap1.example.com -D "cn=manager,ou=admins,dc=example,dc=com" objectClass=* -b dc=example,dc=com -Z
ldapsearch -x -w password -D "cn=manager,ou=admins,dc=example,dc=com" objectClass=* -b dc=example,dc=com -Z
Provider 2번 서버에서 다음 명령 실행:
ldapadd -x -w password -D "cn=manager,ou=admins,dc=example,dc=com" -Z << EOF
dn: cn=Keanu Reeves,ou=people,dc=example,dc=com
objectClass: top
objectClass: posixAccount
objectClass: inetOrgPerson
cn: Keanu Reeves
uid: keanu
sn: Reeves
givenName: Keanu
uidNumber: 1001
gidNumber: 500
homeDirectory: /home/users/keanu
loginShell: /bin/bash
EOF
Provider 1번 서버에서 다음 명령 실행:
ldapsearch -x -w password -D "cn=manager,ou=admins,dc=example,dc=com" uid=keanu -b dc=example,dc=com -Z
kdc1, kdc2 호스트에 필요한 패키지를 설치한다.
- Kerberos 라이브러리, 서버, 클라이언트
- xinetd: kerberos 동기화 용도
yum install -y krb5-server krb5-workstation krb5-libs libkadm5 words
yum install -y xinetd
/etc/krb5.conf
: source code/var/kerberos/krb5kdc/kdc.conf
: source code
krb5 사용자를 관리하는 데이터베이스를 생성한다.
kdb5_util create -r EXAMPLE.COM -s -P password
Loading random data
Initializing database '/var/kerberos/krb5kdc/principal' for realm 'EXAMPLE.COM',
master key name 'K/M@EXAMPLE.COM'
K/M@EXAMPLE.COM
의 비밀번호를 설정한다.
/var/kerberos/krb5kdc/kadm5.acl
: source code
krb5 관리자 목록에 */admin@EXAMPLE.COM
를 추가한다.
admin/admin@EXAMPLE.COM
를 추가하고 비밀번호를 설정한다.
kadmin.local -q 'addprinc -pw password admin/admin@EXAMPLE.COM'
Authenticating as principal root/admin@EXAMPLE.COM with password.
WARNING: no policy specified for admin/admin@EXAMPLE.COM; defaulting to no policy
Principal "admin/admin@EXAMPLE.COM" created.
krb5kdc와 kadmin를 실행한다.
systemctl start krb5kdc
systemctl start kadmin
systemctl enable krb5kdc
systemctl enable kadmin
다음 명령들을 실행하면 /etc/krb5.keytab
라는 파일이 생성된다. 이 파일을 kdc2 서버와 공유해야 한다.
kadmin -p admin/admin -w password -q 'addprinc -randkey host/kdc1.example.com'
kadmin -p admin/admin -w password -q 'addprinc -randkey host/kdc2.example.com'
kadmin -p admin/admin -w password -q 'ktadd host/kdc1.example.com'
kadmin -p admin/admin -w password -q 'ktadd host/kdc2.example.com'
scp -o StrictHostKeyChecking=no /etc/krb5.conf kdc2:/etc/krb5.conf
scp -o StrictHostKeyChecking=no /var/kerberos/krb5kdc/kdc.conf kdc2:/var/kerberos/krb5kdc/kdc.conf
scp -o StrictHostKeyChecking=no /var/kerberos/krb5kdc/kadm5.acl kdc2:/var/kerberos/krb5kdc/kadm5.acl
scp -o StrictHostKeyChecking=no /var/kerberos/krb5kdc/.k5.EXAMPLE.COM kdc2:/var/kerberos/krb5kdc/.k5.EXAMPLE.COM
scp -o StrictHostKeyChecking=no /etc/krb5.keytab kdc2:/etc/krb5.keytab
Master KDC는 kpropd 데몬을 이용해서 복제 KDC 서버로 데이터를 전파한다.
/var/kerberos/krb5kdc/kpropd.acl
: source code/etc/xinetd.d/krb5_prop
: source code
xinetd를 실행한다.
systemctl start xinetd
systemctl enable xinetd
kdb5_util dump /var/kerberos/krb5kdc/replica_datatrans
kprop -f /var/kerberos/krb5kdc/replica_datatrans kdc2.example.com
KDC 2로 데이터 전파가 성공했다.
Database propagation to kdc2.example.com: SUCCEEDED
KDC 2에서 krb5kdc를 실행한다.
systemctl start krb5kdc
systemctl enable krb5kdc
KDC 1에서 동기화 스크립트를 작성한다.
/var/kerberos/krb5kdc/propagator.sh
: source code
실행 권한을 부여한다.
chmod +x /var/kerberos/krb5kdc/propagator.sh
crontab에 작업을 등록한다.
매 분마다 propagator.sh가 실행되어, 복제 KDC 서버로 데이터가 전파된다.
(crontab -l 2>/dev/null; echo "* * * * * /var/kerberos/krb5kdc/propagator.sh") | crontab -
cron 작성을 확인한다.
crontab -l
* * * * * /var/kerberos/krb5kdc/propagator.sh
LDAP 1, LDAP 2 호스트에서 GSSAPI 메커니즘을 사용할 수 있는지 확인한다.
pluginviewer | grep -i gssapi
ldapsearch -LLL -x -H ldapi:/// -s base -b "" supportedSASLMechanisms
dn:
supportedSASLMechanisms: GSS-SPNEGO
supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: EXTERNAL
supportedSASLMechanisms: CRAM-MD5
supportedSASLMechanisms: LOGIN
supportedSASLMechanisms: PLAIN
ldapsearch -LLL -x -H ldap://ldap1.example.com -s base -b "" supportedSASLMechanisms
dn:
supportedSASLMechanisms: GSS-SPNEGO
supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: CRAM-MD5
아직 Kerberos 티켓이 없어 LDAP 서버에 접근할 수가 없다.
ldapsearch -LLL -Y GSSAPI -H ldap://ldap1.example.com -s base -b "" supportedSASLMechanisms
SASL/GSSAPI authentication started
ldap_sasl_interactive_bind_s: Local error (-2)
additional info: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (No Kerberos credentials available (default cache: KEYRING:persistent:1000))
/etc/sasl2/slapd.conf
를 생성한다.
KDC 1 서버에서 LDAP 1, LDAP 2 호스트를 등록하여 keytab 파일을 생성한다.
kadmin -p admin/admin -w password -q 'addprinc -randkey host/ldap1.example.com'
kadmin -p admin/admin -w password -q 'addprinc -randkey host/ldap2.example.com'
kadmin -p admin/admin -w password -q 'addprinc -randkey ldap/ldap1.example.com'
kadmin -p admin/admin -w password -q 'addprinc -randkey ldap/ldap2.example.com'
kadmin -p admin/admin -w password -q 'ktadd -k /etc/ldap.keytab host/ldap1.example.com'
kadmin -p admin/admin -w password -q 'ktadd -k /etc/ldap.keytab host/ldap2.example.com'
kadmin -p admin/admin -w password -q 'ktadd -k /etc/ldap.keytab ldap/ldap1.example.com'
kadmin -p admin/admin -w password -q 'ktadd -k /etc/ldap.keytab ldap/ldap2.example.com'
생성한 keytab 파일을 ldap1, ldap2 서버로 복사한다.
scp -o StrictHostKeyChecking=no /etc/ldap.keytab ldap1:/etc/openldap/ldap.keytab
scp -o StrictHostKeyChecking=no /etc/ldap.keytab ldap2:/etc/openldap/ldap.keytab
ldap1, ldap2에서 keytab 파일 권한을 변경한다.
chmod 660 /etc/openldap/ldap.keytab
chgrp ldap /etc/openldap/ldap.keytab
LDAP 1, LDAP 2의 slapd 설정에 keytab을 등록한다. 파일의 마지막 줄 주석을 해제한다.
echo 'KRB5_KTNAME="FILE:/etc/openldap/ldap.keytab"' >> /etc/sysconfig/slapd
LDAP 1, LDAP 2의 slapd를 모두 재시작한다.
systemctl restart slapd
LDAP 1, LDAP 2 모두 매커니즘 목록을 확인한다.
ldapsearch -LLL -x -H ldapi:/// -s base -b "" supportedSASLMechanisms
dn:
supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: EXTERNAL
ldapsearch -LLL -x -H ldap://ldap1.example.com -s base -b "" supportedSASLMechanisms
ldapsearch -LLL -x -H ldap://ldap2.example.com -s base -b "" supportedSASLMechanisms
dn:
supportedSASLMechanisms: GSSAPI
client 호스트에 필요한 패키지를 설치한다.
- OpenLDAP 라이브러리, 클라이언트
- Kerberos 라이브러리, 클라이언트
- SASL 라이브러리
yum install -y openldap openldap-clients
yum install -y krb5-workstation krb5-libs libkadm5
yum install -y cyrus-sasl cyrus-sasl-gssapi cyrus-sasl-ldap cyrus-sasl-md5 cyrus-sasl-plain
먼저 KDC 1 서버에서 client의 호스트를 등록한다.
kadmin -p admin/admin -w password -q 'addprinc -pw password host/client.example.com'
이제 Client에서 GSSAPI 메커니즘을 사용할 수 있는지 확인한다.
pluginviewer | grep -i gssapi
/etc/openldap/ldap.conf
: source code
Client 호스트에도 KDC 1, KDC 2와 같은 설정을 사용한다.
/etc/krb5.conf
: source code
클라이언트에서 티켓을 받는다.
kinit host/client.example.com
host/client.example.com@EXAMPLE.COM
의 비밀번호(password
)를 입력한다.
티켓을 확인한다.
klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: host/client.example.com@EXAMPLE.COM
Valid starting Expires Service principal
10/29/2020 10:59:09 10/29/2020 22:59:09 krbtgt/EXAMPLE.COM@EXAMPLE.COM
renew until 10/30/2020 10:59:09
LDAP 사용자의 신원을 확인한다.
ldapwhoami -Z
SASL/GSSAPI authentication started
SASL username: host/client.example.com@EXAMPLE.COM
SASL SSF: 256
SASL data security layer installed.
dn:cn=host/client.example.com@example.com,ou=people,dc=example,dc=com
클라이언트에서 GSSAPI를 사용해서 LDAP 서버에 접근한다.
먼저 매커니즘을 확인한다.
ldapsearch -LLL -Y GSSAPI -H ldap://ldap1.example.com -s base -b "" supportedSASLMechanisms
SASL/GSSAPI authentication started
SASL username: host/client.example.com@EXAMPLE.COM
SASL SSF: 256
SASL data security layer installed.
dn:
supportedSASLMechanisms: GSSAPI
전체 엔트리 정보를 검색한다.
ldapsearch -LLL -Y GSSAPI -b "dc=example,dc=com" -Z
ldapsearch -LLL -Y GSSAPI -b dc=example,dc=com uid=keanu -Z
만약 검색 결과가 없다면 다음 명령을 ldap1이나 ldap2에서 적용 후 Client에서 다시 확인한다.
vagrant ssh ldap1
ldapadd -x -w password -D "cn=manager,ou=admins,dc=example,dc=com" -Z << EOF
dn: cn=Keanu Reeves,ou=people,dc=example,dc=com
objectClass: top
objectClass: posixAccount
objectClass: inetOrgPerson
cn: Keanu Reeves
uid: keanu
sn: Reeves
givenName: Keanu
uidNumber: 1001
gidNumber: 500
homeDirectory: /home/users/keanu
loginShell: /bin/bash
EOF
vagrant destroy -f