Merge pull request 'Release of EvoBSD 6.8.0' (#37) from dev into master
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details

Reviewed-on: #37
Reviewed-by: Jérémy Lecour <jlecour@noreply.gitea.evolix.org>
master 6.8.0
Jérémy Lecour 2 years ago
commit f89751669f

@ -0,0 +1,30 @@
---
kind: pipeline
type: docker
name: default
steps:
- name: lint markdown files
image: pipelinecomponents/remark-lint:latest
commands:
- "remark --no-stdout --color --use preset-lint-recommended ."
- name: lint yaml files
image: pipelinecomponents/yamllint:latest
commands:
- "yamllint ."
- name: lint ansible scripts
image: pipelinecomponents/ansible-lint:latest
commands:
- >
find . -maxdepth 1 -name '*.yml'
| sort
| grep -v '.drone.yml'
| xargs ansible-playbook --syntax-check --list-tasks
- >
find . -maxdepth 1 -name '*.yml'
| sort
| grep -v '.drone.yml'
| xargs ansible-lint

@ -0,0 +1,75 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [6.8.0] - 2020-10-23
### Added
- Add a PF tag to be able to skip that part when rerunning EvoBSD
- Add a doas authorization for NRPE check_ipsecctl_critiques
### Changed
- The task mail.yml replace the former boot/reboot message only if it is untouched
- Replace the variable used to set the email address in etc-git role - now using inventory_hostname
- Not checking syspatch when OpenBSD <= 6.1
- Amend fstab file adding noatime option to each entrie
- Import evocheck v.6.7.7
- Comment NRPE checks that cannot be used as is
### Fixed
- Add the creation of the NRPE plugins directory in nagios-nrpe role
- Add collectd doas rights in the base role to avoid broking anything if EvoBSD is rerun without the collectd role included
- Do not add the motd cron if the same line is already there but uncommented
- Amend fstab entries only when the filesystem is ffs
## [6.7.2] - 2020-10-13
### Added
- Now handling deletion of evobackup crontab (replaced by daily.local cron)
- Customize fstab with noexec and softdep
- Collectd role
### Changed
- Improve rc.local file configuration
- Update evocheck to version 6.7.5
- Hide default daily output mail content (VERBOSESTATUS=0)
- Add deletion of old log files in the OSPF role
### Fixed
- Fix duplicate evobackup cron if the entry is uncommented in daily.local
## [6.7.1] - 2020-09-10
### Added
- Add completions functions in root's profile dotfile
- Add check_connections_state.sh NRPE plugin
- Add an evocheck role
- Add stricter ssh and doas access
- Add an openvpn role
- Add an OpenBGPd NRPE plugin
- Add ospf and bgp roles
- Add an unbound NRPE check since it is part of the base system
- Add a motd-carp-state.sh script that checks the carp state and generates the /etc/motd file
### Changed
- Disable sndiod since it is not required on serveurs
- Replace sudo with doas for script executions
- Update evomaintenance version to 0.6.3
- Disable mouse function in vim configuration
- Drop openup since syspatch can apply stable patches now
- Update evobackup script
- Rewrite newsyslog configuration
- Drop postgresql-client package since evomaintenance use an API now

@ -2,17 +2,17 @@
Contributions are welcome, as long as they respect our current workflow:
1. The master branch is only for releases. Once properly tested,
the dev branch can be merged, the release tagged and a tar archive
created.
1. The master branch is only for releases. Once properly tested,
the dev branch can be merged, the release tagged and a tar archive
created.
2. The dev branch should never be commited to directly, unless
you're updating the CHANGELOG file.
2. The dev branch should never be commited to directly, unless
you're updating the CHANGELOG file.
3. Use feature branches for anything else, once they've passed all
CI tests and have been reviewed by other contributors through a
pull request, they may be merged into the dev branch.
3. Use feature branches for anything else, once they've passed all
CI test, lints and have been reviewed by other contributors through a
pull request, they may be merged into the dev branch.
Open issues liberally, but please review closed and opened issues
for duplicates before hand.
for duplicates before hand.

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2019 Evolix
Copyright (c) 2020 Evolix
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

@ -1,4 +1,4 @@
# EvoBSD 1.0
# EvoBSD 6.8.0
EvoBSD is an ansible project used for customising OpenBSD hosts
used by Evolix.
@ -9,16 +9,24 @@ used by Evolix.
Put your public key in the remote root's autorized_keys
(/root/.ssh/authorized_keys)
1 - Install ansible's prerequisites
1. Install ansible's prerequisites
```
ansible-playbook prerequisite.yml -CDi hosts -l HOSTNAME
```
2 - Run it
2. Run it
First use (become_method: su) :
```
ansible-playbook evolixisation.yml --ask-vault-pass -CDki hosts -u root -l HOSTNAME
```
Subsequent use (become_method: sudo) :
```
ansible-playbook evolixisation.yml --ask-vault-pass -CDKi hosts -l HOSTNAME
ansible-playbook evolixisation.yml --ask-vault-pass -CDKi hosts --skip-tags pf -l HOSTNAME
```
### Testing
@ -26,100 +34,40 @@ ansible-playbook evolixisation.yml --ask-vault-pass -CDKi hosts -l HOSTNAME
Changes can be tested by using [Packer](https://www.packer.io/) and
[vmm(4)](https://man.openbsd.org/vmm.4) :
* This process depends on the [Go](https://golang.org/) programming language.
* This process depends on the [Go](https://golang.org/) programming language.
```
# pkg_add go packer
```
**Packages**
* We use the [packer-builder-vmm](https://github.com/prep/packer-builder-vmm) project to bridge Packer and vmm(4)
Needing a Golang eco system and some basics
```
$ go get -u github.com/prep/packer-builder-vmm/cmd/packer-builder-vmm
```
````
pkg_add go-- packer-- git--
````
* Here is an example build file
* We use the [packer-builder-openbsd-vmm](https://github.com/double-p/packer-builder-openbsd-vmm) project to bridge Packer and vmm(4)
```
$ vim openbsd.json
```
````
git clone https://github.com/double-p/packer-builder-openbsd-vmm.git
````
{
"description": "OpenBSD installation on vmm(4)",
"variables": {
"hostname": "evobsd",
"domain": "example.com",
"password": "evolix"
},
"builders": [
{
"type": "vmm",
"vm_name": "evobsd",
"disk_size": "2G",
"format": "qcow2",
"mem_size": "1024M",
"iso_urls": ["downloads/install64.fs", "https://ftp.nluug.nl/pub/OpenBSD/6.4/amd64/install64.fs"],
"iso_checksum": "7aa4344cb39efbf67300f97ac7eec005b607e8c19d4e31a0a593a8ee2b7136e4",
"iso_checksum_type": "sha256",
"boot_wait": "10s",
"boot_command": [
"S<enter>",
"cat <<EOF >disklabel.template<enter>",
"/ 1G-* 100%<enter>",
"EOF<enter>",
"cat <<EOF >install.conf<enter>",
"System hostname = {{user `hostname`}}<enter>",
"DNS domain name = {{user `domain`}}<enter>",
"Password for root account = {{user `password`}}<enter>",
"Do you expect to run the X Window System = no<enter>",
"Setup a user = no<enter>",
"Which disk is the root disk = sd1<enter>",
"Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout = c<enter>",
"URL to autopartitioning template for disklabel = file://disklabel.template<enter>",
"Location of sets = disk<enter>",
"Is the disk partition already mounted = no<enter>",
"Set name(s) = -bsd.rd<enter>",
"Set name(s) = done<enter>",
"Directory does not contain SHA256.sig. Continue without verification = yes<enter>",
"What timezone are you in = Europe/Paris<enter>",
"EOF<enter>",
"install -af install.conf<enter>",
"<wait2m>",
"/sbin/halt -p<enter><wait15>"
]
}
]
}
* You need your unprivileged user to be able to run vmctl(8) through doas(1)
```
# echo "permit nopass myunprivilegeduser as root cmd /usr/sbin/vmctl" >> /etc/doas.conf
```
**builds**
* Build the virtual machine
Set ````GOPATH```` (default: ~/go), if the 1.4GB dependencies wont fit.
```
$ packer build openbsd.json
```
````
make
make install
````
* Start it
* You need your unprivileged user to be able to run vmctl(8) through doas(1)
```
doas vmctl start evobsd -cL -d output-vmm/evobsd.qcow2
echo "permit nopass myunprivilegeduser as root cmd /usr/sbin/vmctl" >> /etc/doas.conf
```
* Enable NAT on your host machine
See packer-builder-openbsd-vmm/examples/README.examples for further instructions
* Enable NAT on your host machine
```
pass out on em0 inet from tap0:network to any nat-to (em0)

@ -1,5 +1,9 @@
# yamllint disable rule:line-length
# Playbook command
# ansible-playbook evolixisation.yml --ask-vault-pass -CDKi hosts -l HOSTNAME
# First use (become_method: su) :
# ansible-playbook evolixisation.yml --ask-vault-pass -CDki hosts -u root -l HOSTNAME
# Subsequent use (become_method: sudo) :
# ansible-playbook evolixisation.yml --ask-vault-pass -CDKi hosts --skip-tags pf -l HOSTNAME
---
- name: Evolixisation of an OpenBSD system
@ -7,11 +11,13 @@
become: true
become_user: root
become_method: sudo
# become_method: su
vars_files:
- vars/main.yml
# - vars/secrets.yml
- vars/secrets.yml
- vars/openbsd-secret.yml
roles:
- etc-git
@ -20,14 +26,20 @@
- pf
- accounts
- nagios-nrpe
- evocheck
- post-install
# - openvpn
# - ospf
# - bgp
# - { role: collectd, collectd_server: "127.0.0.1" }
post_tasks:
- include: "tasks/commit_etc_git.yml"
vars:
commit_message: "Ansible - Evolixisation"
- include_role:
name: evocheck
tasks_from: exec.yml
environment:
PKG_PATH: "http://ftp.openbsd.org/pub/OpenBSD/{{ ansible_distribution_version }}/packages/{{ ansible_architecture }}/"
# vim:ft=ansible
# environment:
# PKG_PATH: "http://ftp.openbsd.org/pub/OpenBSD/{{ ansible_distribution_version }}/packages/{{ ansible_architecture }}/"

@ -2,4 +2,4 @@
foo.example.com
[openbsd:vars]
ansible_python_interpreter=/usr/local/bin/python2.7
ansible_python_interpreter=/usr/local/bin/python3

@ -2,15 +2,16 @@
# ansible-playbook prerequisite.yml -CDi hosts -l HOSTNAME
---
- hosts: all
become: yes
become_method: su
user: root
gather_facts: no
- hosts: all
become: true
become_method: su
user: root
gather_facts: false
tasks:
tasks:
- name: Install ansible's prerequisite
raw: export PKG_PATH=http://ftp.eu.openbsd.org/pub/OpenBSD/$(uname -r)/packages/$(uname -p)/; pkg_add -z python-2
# yamllint disable-line rule:line-length
raw: export PKG_PATH=http://ftp.eu.openbsd.org/pub/OpenBSD/$(uname -r)/packages/$(uname -p)/; pkg_add -z python-3
# vim:ft=ansible

@ -0,0 +1,6 @@
---
- name: reload sshd
service:
name: sshd
state: reloaded

@ -1,7 +1,85 @@
---
- name: "Create {{ evobsd_ssh_group }} group"
group:
name: "{{ evobsd_ssh_group }}"
system: true
- name: "Create {{ evobsd_sudo_group }} group"
group:
name: "{{ evobsd_sudo_group }}"
system: true
- name: Create user accounts
include: user.yml
vars:
user: "{{ item.value }}"
with_dict: "{{ evolinux_users }}"
when: evolinux_users != {}
with_dict: "{{ evolix_users }}"
when: evolix_users != {}
- name: verify AllowGroups directive
command: "grep -E '^AllowGroups' /etc/ssh/sshd_config"
changed_when: false
failed_when: false
check_mode: false
register: grep_allowgroups_ssh
- name: verify AllowUsers directive
command: "grep -E '^AllowUsers' /etc/ssh/sshd_config"
changed_when: false
failed_when: false
check_mode: false
register: grep_allowusers_ssh
- name: "Check that AllowUsers and AllowGroup do not override each other"
assert:
that: "not (grep_allowusers_ssh.rc == 0 and grep_allowgroups_ssh.rc == 0)"
msg: "We can't deal with AllowUsers and AllowGroups at the same time"
- name: "If AllowGroups is present then use it"
set_fact:
ssh_allowgroups:
"{{ (grep_allowgroups_ssh.rc == 0) or (grep_allowusers_ssh.rc != 0) }}"
- name: "Add AllowGroups sshd directive with '{{ evobsd_ssh_group }}'"
lineinfile:
dest: /etc/ssh/sshd_config
line: "\nAllowGroups {{ evobsd_ssh_group }}"
insertafter: 'Subsystem'
validate: '/usr/sbin/sshd -t -f %s'
notify: reload sshd
when:
- ssh_allowgroups
- grep_allowgroups_ssh.rc == 1
- name: "Append '{{ evobsd_ssh_group }}' to AllowGroups sshd directive"
replace:
dest: /etc/ssh/sshd_config
regexp: '^(AllowGroups ((?!\b{{ evobsd_ssh_group }}\b).)*)$'
replace: '\1 {{ evobsd_ssh_group }}'
validate: '/usr/sbin/sshd -t -f %s'
notify: reload sshd
when:
- ssh_allowgroups
- grep_allowgroups_ssh.rc == 0
- name: "Security directives for EvoBSD"
blockinfile:
dest: /etc/ssh/sshd_config
marker: "# {mark} EVOBSD PASSWORD RESTRICTIONS"
block: |
Match Address {{ evolix_trusted_ips | join(',') }}
PasswordAuthentication yes
Match Group {{ evobsd_ssh_group }}
PasswordAuthentication no
insertafter: EOF
validate: '/usr/sbin/sshd -t -f %s'
notify: reload sshd
when:
- evolix_trusted_ips != []
- name: "Disable root login"
replace:
dest: /etc/ssh/sshd_config
regexp: '^PermitRootLogin (yes|without-password|prohibit-password)'
replace: "PermitRootLogin no"
notify: reload sshd

@ -1,16 +1,31 @@
---
- name: "Group '{{ user.name }}' is present"
group:
state: present
name: "{{ user.name }}"
gid: "{{ user.uid }}"
- name: "User '{{ user.name }}' is present"
user:
state: present
name: '{{ user.name }}'
uid: '{{ user.uid }}'
password: '{{ user.password_hash_openbsd }}'
group: "{{ user.name }}"
groups: wheel
shell: /bin/ksh
append: yes
append: true
tags:
- admin
- name: "Home directory for '{{ user.name }}' is only accesible by owner"
file:
name: '/home/{{ user.name }}'
mode: "0700"
owner: "{{ user.name }}"
group: "{{ user.name }}"
state: directory
- name: "SSH public keys for '{{ user.name }}' are present"
authorized_key:
user: "{{ user.name }}"
@ -21,4 +36,20 @@
loop_var: ssk_key
when: user.ssh_keys is defined
tags:
- admin
- admin
- name: "Add {{ user.name }} to {{ evobsd_ssh_group }} group"
user:
name: "{{ user.name }}"
groups: "{{ evobsd_ssh_group }}"
append: true
tags:
- admin
- name: "Add {{ user.name }} to {{ evobsd_sudo_group }} group"
user:
name: "{{ user.name }}"
groups: "{{ evobsd_sudo_group }}"
append: true
tags:
- admin

@ -1,19 +1,39 @@
---
ntpd_servers:
- "ntp.evolix.net"
- "ntp.evolix.net"
general_alert_email: "root@localhost"
general_technical_realm: "example.com"
evomaintenance_realm: "example.com"
evomaintenance_alert_email: "evomaintenance-{{ inventory_hostname }}@{{ evomaintenance_realm }}"
evomaintenance_hostname: "{{ inventory_hostname }}.{{ general_technical_realm }}"
evomaintenance_pg_host: Null
evomaintenance_pg_passwd: Null
evomaintenance_pg_db: Null
evomaintenance_pg_table: Null
evomaintenance_alert_email:
"evomaintenance-{{ inventory_hostname }}@{{ evomaintenance_realm }}"
evomaintenance_hostname:
"{{ inventory_hostname }}.{{ general_technical_realm }}"
evomaintenance_pg_host: null
evomaintenance_pg_passwd: null
evomaintenance_pg_db: null
evomaintenance_pg_table: null
evomaintenance_from_domain: "{{ evomaintenance_realm }}"
evomaintenance_from: "evomaintenance@{{ evomaintenance_from_domain }}"
evomaintenance_full_from: "Evomaintenance <{{ evomaintenance_from }}>"
evomaintenance_urgency_from: mama.doe@example.com
evomaintenance_urgency_tel: "06.00.00.00.00"
evomaintenance_install_vendor: false
evomaintenance_force_config: true
evomaintenance_api_endpoint: null
evomaintenance_api_key: null
evomaintenance_hook_api: true
evomaintenance_hook_db: false
evomaintenance_hook_commit: true
evomaintenance_hook_mail: true
evomaintenance_default_hosts: []
evomaintenance_additional_hosts: []
evomaintenance_hosts: >
{{ evomaintenance_default_hosts
| union(evomaintenance_additional_hosts)
| unique }}
evobsd_path: >-
"$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
cron_root_path: "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"

@ -4,82 +4,489 @@
# Dependencies (all OS): git postgresql-client
# Dependencies (Debian): sudo
# version 0.4.1
# Copyright 2007-2018 Evolix <info@evolix.fr>
# Copyright 2007-2019 Evolix <info@evolix.fr>, Gregory Colpart <reg@evolix.fr>,
# Jérémy Lecour <jlecour@evolix.fr> and others.
VERSION="0.6.3"
show_version() {
cat <<END
evomaintenance version ${VERSION}
Copyright 2007-2019 Evolix <info@evolix.fr>,
Gregory Colpart <reg@evolix.fr>,
Jérémy Lecour <jlecour@evolix.fr>
and others.
evomaintenance comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
See the GNU General Public Licence for details.
END
}
show_help() {
cat <<END
evomaintenance is a program that helps reporting what you've done on a server
Usage: evomaintenance
or evomaintenance --message="add new host"
or evomaintenance --no-api --no-mail --no-commit
or echo "add new vhost" | evomaintenance
Options
-m, --message=MESSAGE set the message from the command line
--mail enable the mail hook (default)
--no-mail disable the mail hook
--db enable the database hook
--no-db disable the database hook (default)
--api enable the API hook (default)
--no-api disable the API hook
--commit enable the commit hook (default)
--no-commit disable the commit hook
--evocheck enable evocheck execution (default)
--no-evocheck disable evocheck execution
--auto use "auto" mode
--no-auto use "manual" mode (default)
-v, --verbose increase verbosity
-n, --dry-run actions are not executed
--help print this message and exit
--version print version and exit
END
}
syslog() {
if [ -x "${LOGGER_BIN}" ]; then
${LOGGER_BIN} -t "evomaintenance" "$1"
fi
}
get_system() {
uname -s
uname -s
}
get_fqdn() {
if [ "$(get_system)" = "Linux" ]; then
hostname --fqdn
elif [ "$(get_system)" = "OpenBSD" ]; then
hostname
else
echo "OS not detected!"
exit 1
fi
if [ "$(get_system)" = "Linux" ]; then
hostname --fqdn
elif [ "$(get_system)" = "OpenBSD" ]; then
hostname
else
echo "OS not detected!"
exit 1
fi
}
get_tty() {
if [ "$(get_system)" = "Linux" ]; then
ps -o tty= | tail -1
elif [ "$(get_system)" = "OpenBSD" ]; then
env | grep SSH_TTY | cut -d"/" -f3
else
echo "OS not detected!"
exit 1
fi
if [ "$(get_system)" = "Linux" ]; then
ps -o tty= | tail -1
elif [ "$(get_system)" = "OpenBSD" ]; then
env | grep SSH_TTY | cut -d"/" -f3
else
echo "OS not detected!"
exit 1
fi
}
get_who() {
who=$(LC_ALL=C who -m)
who=$(LC_ALL=C who -m | tr -s ' ')
if [ -n "${who}" ]; then
echo "${who}"
else
LC_ALL=C who | grep $(get_tty) | tr -s ' '
fi
if [ -n "${who}" ]; then
echo "${who}"
else
LC_ALL=C who | grep "$(get_tty)" | tr -s ' '
fi
}
get_begin_date() {
echo "$(date "+%Y") $(echo $(get_who) | cut -d" " -f3,4,5)"
printf "%s %s" "$(date "+%Y")" "$(get_who | cut -d" " -f3,4,5)"
}
get_ip() {
ip=$(echo $(get_who) | cut -d" " -f6 | sed -e "s/^(// ; s/)$//")
[ -z "${ip}" ] && ip="unknown (no tty)"
[ "${ip}" = ":0" ] && ip="localhost"
ip=$(get_who | cut -d" " -f6 | sed -e "s/^(// ; s/)$//")
[ -z "${ip}" ] && ip="unknown (no tty)"
[ "${ip}" = ":0" ] && ip="localhost"
echo "${ip}"
echo "${ip}"
}
get_end_date() {
date +"%Y %b %d %H:%M"
date +"%Y %b %d %H:%M"
}
get_now() {
date +"%Y-%m-%dT%H:%M:%S%z"
date +"%Y-%m-%dT%H:%M:%S%z"
}
get_complete_hostname() {
REAL_HOSTNAME=$(get_fqdn)
if [ "${HOSTNAME}" = "${REAL_HOSTNAME}" ]; then
echo "${HOSTNAME}"
else
echo "${HOSTNAME} (${REAL_HOSTNAME})"
fi
}
get_repository_status() {
dir=$1
# tell Git where to find the repository and the work tree (no need to `cd …` there)
export GIT_DIR="${dir}/.git" GIT_WORK_TREE="${dir}"
# If the repository and the work tree exist, try to commit changes
if [ -d "${GIT_DIR}" ] && [ -d "${GIT_WORK_TREE}" ]; then
CHANGED_LINES=$(${GIT_BIN} status --porcelain | wc -l | tr -d ' ')
if [ "${CHANGED_LINES}" != "0" ]; then
STATUS=$(${GIT_BIN} status --short | tail -n ${GIT_STATUS_MAX_LINES})
printf "%s\n%s\n" "${GIT_DIR} (last ${GIT_STATUS_MAX_LINES} lines)" "${STATUS}" | sed -e '/^$/d'
fi
fi
# unset environment variables to prevent accidental influence on other git commands
unset GIT_DIR GIT_WORK_TREE
}
get_evocheck() {
if [ -x "${EVOCHECK_BIN}" ]; then
printf "Evocheck status :"
EVOCHECK_OUT=$(${EVOCHECK_BIN})
EVOCHECK_RC=$?
if [ "${EVOCHECK_RC}" = "0" ] && [ -z "${EVOCHECK_OUT}" ]; then
printf " OK\n\n"
else
printf " ERROR\n%s\n\n" "${EVOCHECK_OUT}"
fi
fi
}
print_log() {
printf "*********** %s ***************\n" "$(get_now)"
print_session_data
printf "Hooks : commit=%s db=%s api=%s mail=%s\n"\
"${HOOK_COMMIT}" "${HOOK_DB}" "${HOOK_API}" "${HOOK_MAIL}"
if [ "${HOOK_MAIL}" = "1" ]; then
printf "Mailto : %s\n" "${EVOMAINTMAIL}"
fi
}
print_session_data() {
printf "Host : %s\n" "${HOSTNAME_TEXT}"
printf "User : %s\n" "${USER}"
printf "IP : %s\n" "${IP}"
printf "Begin : %s\n" "${BEGIN_DATE}"
printf "End : %s\n" "${END_DATE}"
printf "Message : %s\n" "${MESSAGE}"
}
is_repository_readonly() {
if [ "$(get_system)" = "OpenBSD" ]; then
partition=$(stat -f '%Sd' $1)
mount | grep ${partition} | grep -q "read-only"
else
mountpoint=$(stat -c '%m' $1)
findmnt ${mountpoint} --noheadings --output OPTIONS -O ro
fi
}
remount_repository_readwrite() {
if [ "$(get_system)" = "OpenBSD" ]; then
partition=$(stat -f '%Sd' $1)
mount -u -w /dev/${partition} 2>/dev/null
else
mountpoint=$(stat -c '%m' $1)
mount -o remount,rw ${mountpoint}
syslog "Re-mount ${mountpoint} as read-write to commit in repository $1"
fi
}
remount_repository_readonly() {
if [ "$(get_system)" = "OpenBSD" ]; then
partition=$(stat -f '%Sd' $1)
mount -u -r /dev/${partition} 2>/dev/null
else
mountpoint=$(stat -c '%m' $1)
mount -o remount,ro ${mountpoint} 2>/dev/null
syslog "Re-mount ${mountpoint} as read-only after commit to repository $1"
fi
}
hook_commit() {
if [ -x "${GIT_BIN}" ]; then
# loop on possible directories managed by GIT
for dir in ${GIT_REPOSITORIES}; do
# tell Git where to find the repository and the work tree (no need to `cd …` there)
export GIT_DIR="${dir}/.git" GIT_WORK_TREE="${dir}"
# reset variable used to track if a mount point is readonly
READONLY_ORIG=0
# If the repository and the work tree exist, try to commit changes
if [ -d "${GIT_DIR}" ] && [ -d "${GIT_WORK_TREE}" ]; then
CHANGED_LINES=$(${GIT_BIN} status --porcelain | wc -l | tr -d ' ')
if [ "${CHANGED_LINES}" != "0" ]; then
if [ "${DRY_RUN}" = "1" ]; then
# STATS_SHORT=$(${GIT_BIN} diff --stat | tail -1)
STATS=$(${GIT_BIN} diff --stat | tail -n ${GIT_STATUS_MAX_LINES})
# GIT_COMMITS_SHORT=$(printf "%s\n%s : %s" "${GIT_COMMITS_SHORT}" "${GIT_DIR}" "${STATS_SHORT}" | sed -e '/^$/d')
GIT_COMMITS=$(printf "%s\n%s\n%s" "${GIT_COMMITS}" "${GIT_DIR}" "${STATS}" | sed -e '/^$/d')
else
# remount mount point read-write if currently readonly
is_repository_readonly ${dir} && { READONLY_ORIG=1; remount_repository_readwrite ${dir}; }
# commit changes
${GIT_BIN} add --all
${GIT_BIN} commit --message "${MESSAGE}" --author="${USER} <${USER}@evolix.net>" --quiet
# remount mount point read-only if it was before
test "$READONLY_ORIG" = "1" && remount_repository_readonly ${dir}
# Add the SHA to the log file if something has been committed
SHA=$(${GIT_BIN} rev-parse --short HEAD)
# STATS_SHORT=$(${GIT_BIN} show --stat | tail -1)
STATS=$(${GIT_BIN} show --stat --pretty=format:"" | tail -n ${GIT_STATUS_MAX_LINES})
# append commit data, without empty lines
# GIT_COMMITS_SHORT=$(printf "%s\n%s : %s %s" "${GIT_COMMITS_SHORT}" "${GIT_DIR}" "${SHA}" "${STATS_SHORT}" | sed -e '/^$/d')
GIT_COMMITS=$(printf "%s\n%s : %s\n%s" "${GIT_COMMITS}" "${GIT_DIR}" "${SHA}" "${STATS}" | sed -e '/^$/d')
fi
fi
fi
# unset environment variables to prevent accidental influence on other git commands
unset GIT_DIR GIT_WORK_TREE
done
if [ -n "${GIT_COMMITS}" ]; then
# if [ "${VERBOSE}" = "1" ]; then
printf "\n********** Commits ****************\n%s\n***********************************\n" "${GIT_COMMITS}"
# fi
if [ "${DRY_RUN}" != "1" ]; then
echo "${GIT_COMMITS}" >> "${LOGFILE}"
fi
fi
fi
}
hook_db() {
SQL_DETAILS=$(echo "${MESSAGE}" | sed "s/'/''/g")
PG_QUERY="INSERT INTO evomaint(hostname,userid,ipaddress,begin_date,end_date,details) VALUES ('${HOSTNAME}','${USER}','${IP}','${BEGIN_DATE}',now(),'${SQL_DETAILS}')"
if [ "${VERBOSE}" = "1" ]; then
printf "\n********** DB query **************\n%s\n***********************************\n" "${PG_QUERY}"
fi
if [ "${DRY_RUN}" != "1" ] && [ -x "${PSQL_BIN}" ]; then
echo "${PG_QUERY}" | ${PSQL_BIN} "${PGDB}" "${PGTABLE}" -h "${PGHOST}"
fi
}
hook_api() {
if [ "${VERBOSE}" = "1" ]; then
printf "\n********** API call **************\n"
printf "curl -f -s -S -X POST [REDACTED] -k -F api_key=[REDACTED] -F action=insertEvoMaintenance -F hostname=%s -F userid=%s -F ipaddress=%s -F begin_date=%s -F end_date='now()' -F details=%s" \
"${HOSTNAME}" "${USER}" "${IP}" "${BEGIN_DATE}" "${MESSAGE}"
printf "\n***********************************\n"
fi
if [ "${DRY_RUN}" != "1" ] && [ -x "${CURL_BIN}" ]; then
API_RETURN_STATUS=$(curl -f -s -S -X POST \
"${API_ENDPOINT}" -k \
-F api_key="${API_KEY}" \
-F action=insertEvoMaintenance \
-F hostname="${HOSTNAME}" \
-F userid="${USER}" \
-F ipaddress="${IP}" \
-F begin_date="${BEGIN_DATE}" \
-F end_date='now()' \
-F details="${MESSAGE}")
# either cURL or the API backend can throw an error, otherwise it returns this JSON response
if [ "$API_RETURN_STATUS" = '{"status":"Ok"}' ]; then
echo "API call OK."
else
echo "API call FAILED."
fi
fi
}
format_mail() {
cat <<EOTEMPLATE
From: ${FULLFROM}
Content-Type: text/plain; charset=UTF-8
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
To: ${EVOMAINTMAIL}
Subject: [evomaintenance] Intervention sur ${HOSTNAME_TEXT} (${USER})
Bonjour,
Une intervention vient de se terminer sur votre serveur.
Nom du serveur : ${HOSTNAME_TEXT}
Personne ayant réalisée l'intervention : ${USER}
Intervention réalisée depuis : ${IP}
Début de l'intervention : ${BEGIN_DATE}
Fin de l'intervention : ${END_DATE}
### Renseignements sur l'intervention
${MESSAGE}
###
EOTEMPLATE
if [ -n "${GIT_COMMITS}" ]; then
cat << EOTEMPLATE
### Commits
${GIT_COMMITS}
###
EOTEMPLATE
fi
cat <<EOTEMPLATE
Pour réagir à cette intervention, vous pouvez répondre à ce message
(sur l'adresse mail ${FROM}). En cas d'urgence, utilisez
l'adresse ${URGENCYFROM} ou notre téléphone portable d'astreinte
(${URGENCYTEL})
Cordialement,
--
${FULLFROM}
EOTEMPLATE
}
hook_mail() {
MAIL_CONTENT=$(format_mail)
if [ "${VERBOSE}" = "1" ]; then
printf "\n********** Mail *******************\n%s\n***********************************\n" "${MAIL_CONTENT}"
fi
if [ "${DRY_RUN}" != "1" ] && [ -x "${SENDMAIL_BIN}" ]; then
echo "${MAIL_CONTENT}" | ${SENDMAIL_BIN} -oi -t -f "${FROM}"
fi
}
hook_log() {
if [ "${VERBOSE}" = "1" ]; then
print_log
fi
if [ "${DRY_RUN}" != "1" ]; then
print_log >> "${LOGFILE}"
fi
}
# load configuration if present.
test -f /etc/evomaintenance.cf && . /etc/evomaintenance.cf
[ -n "${HOSTNAME}" ] || HOSTNAME=$(get_fqdn)
[ -n "${EVOMAINTMAIL}" ] || EVOMAINTMAIL=evomaintenance-$(echo "${HOSTNAME}" | cut -d- -f1)@${REALM}
[ -n "${LOGFILE}" ] || LOGFILE=/var/log/evomaintenance.log
HOSTNAME=${HOSTNAME:-$(get_fqdn)}
EVOMAINTMAIL=${EVOMAINTMAIL:-"evomaintenance-$(echo "${HOSTNAME}" | cut -d- -f1)@${REALM}"}
LOGFILE=${LOGFILE:-"/var/log/evomaintenance.log"}
HOOK_COMMIT=${HOOK_COMMIT:-"1"}
HOOK_DB=${HOOK_DB:-"0"}
HOOK_API=${HOOK_API:-"1"}
HOOK_MAIL=${HOOK_MAIL:-"1"}
DRY_RUN=${DRY_RUN:-"0"}
VERBOSE=${VERBOSE:-"0"}
AUTO=${AUTO:-"0"}
EVOCHECK=${EVOCHECK:-"0"}
GIT_STATUS_MAX_LINES=${GIT_STATUS_MAX_LINES:-20}
API_ENDPOINT=${API_ENDPOINT:-""}
# initialize variables
MESSAGE=""
# GIT_COMMITS_SHORT=""
GIT_COMMITS=""
# Parse options
# based on https://gist.github.com/deshion/10d3cb5f88a21671e17a
while :; do
case $1 in
-h|-\?|--help)
show_help
exit 0
;;
-V|--version)
show_version
exit 0
;;
-m|--message)
# message options, with value speparated by space
if [ -n "$2" ]; then
MESSAGE=$2
shift
else
printf 'ERROR: "--message" requires a non-empty option argument.\n' >&2
exit 1
fi
;;
--message=?*)
# message options, with value speparated by =
MESSAGE=${1#*=}
;;
--message=)
# message options, without value
printf 'ERROR: "--message" requires a non-empty option argument.\n' >&2
exit 1
;;
--no-commit)
# disable commit hook
HOOK_COMMIT=0
;;
--commit)
# enable commit hook
HOOK_COMMIT=1
;;
--no-db)
# disable DB hook
HOOK_DB=0
;;
--db)
# enable DB hook
HOOK_DB=1
;;
--no-api)
# disable API hook
HOOK_API=0
;;
--api)
# enable API hook
HOOK_API=1
;;
--no-mail)
# disable mail hook
HOOK_MAIL=0
;;
--mail)
# enable mail hook
HOOK_MAIL=1
;;
--no-auto)
# use "manual" mode
AUTO=0
;;
--auto)
# use "auto" mode
AUTO=1
;;
-n|--dry-run)
# disable actual commands
DRY_RUN=1
;;
-v|--verbose)
# print verbose information
VERBOSE=1
;;
--)
# End of all options.
shift
break
;;
-?*|[[:alnum:]]*)
# ignore unknown options
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
;;
*)
# Default case: If no more options then break out of the loop.
break
;;
esac
shift
done
# Treat unset variables as an error when substituting.
# Only after this line, because some config variables might be missing.
set -u
REAL_HOSTNAME=$(get_fqdn)
if [ "${HOSTNAME}" = "${REAL_HOSTNAME}" ]; then
HOSTNAME_TEXT="${HOSTNAME}"
else
HOSTNAME_TEXT="${HOSTNAME} (${REAL_HOSTNAME})"
fi
# Gather information
HOSTNAME_TEXT=$(get_complete_hostname)
# TTY=$(get_tty)
# WHO=$(get_who)
IP=$(get_ip)
@ -90,109 +497,281 @@ USER=$(logname)
PATH=${PATH}:/usr/sbin
SENDMAIL_BIN=$(command -v sendmail)
readonly SENDMAIL_BIN
if [ "${HOOK_MAIL}" = "1" ] && [ -z "${SENDMAIL_BIN}" ]; then
echo "No \`sendmail' command has been found, can't send mail." 2>&1
fi
GIT_BIN=$(command -v git)
readonly GIT_BIN
if [ "${HOOK_COMMIT}" = "1" ] && [ -z "${GIT_BIN}" ]; then
echo "No \`git' command has been found, can't commit changes" 2>&1
fi
GIT_REPOSITORIES="/etc /etc/bind"
PSQL_BIN=$(command -v psql)
readonly PSQL_BIN
if [ "${HOOK_DB}" = "1" ] && [ -z "${PSQL_BIN}" ]; then
echo "No \`psql' command has been found, can't save to the database." 2>&1
fi
# git statuses
GIT_STATUSES=""
CURL_BIN=$(command -v curl)
readonly CURL_BIN
if [ "${HOOK_API}" = "1" ] && [ -z "${CURL_BIN}" ]; then
echo "No \`curl' command has been found, can't call the API." 2>&1
fi
if test -x "${GIT_BIN}"; then
LOGGER_BIN=$(command -v logger)
readonly LOGGER_BIN
if [ "${HOOK_API}" = "1" ] && [ -z "${API_ENDPOINT}" ]; then
echo "No API endpoint specified, can't call the API." 2>&1
fi
EVOCHECK_BIN="/usr/share/scripts/evocheck.sh"
GIT_REPOSITORIES="/etc /etc/bind /usr/share/scripts"
# initialize variable
GIT_STATUSES=""
# git statuses
if [ -x "${GIT_BIN}" ]; then
# loop on possible directories managed by GIT
for dir in ${GIT_REPOSITORIES}; do
# tell Git where to find the repository and the work tree (no need to `cd …` there)
export GIT_DIR="${dir}/.git" GIT_WORK_TREE="${dir}"
# If the repository and the work tree exist, try to commit changes
if test -d "${GIT_DIR}" && test -d "${GIT_WORK_TREE}"; then
CHANGED_LINES=$(${GIT_BIN} status --porcelain | wc -l | tr -d ' ')
if [ "${CHANGED_LINES}" != "0" ]; then
STATUS=$(${GIT_BIN} status --short | tail -n 10)
# append diff data, without empty lines
GIT_STATUSES=$(printf "%s\n%s\n%s\n" "${GIT_STATUSES}" "${GIT_DIR} (last 10 lines)" "${STATUS}" | sed -e '/^$/d')
fi
RESULT=$(get_repository_status "${dir}")
if [ -n "${RESULT}" ]; then
# append diff data, without empty lines
GIT_STATUSES=$(printf "%s\n%s\n" "${GIT_STATUSES}" "${RESULT}" | sed -e '/^$/d')
fi
# unset environment variables to prevent accidental influence on other git commands
unset GIT_DIR GIT_WORK_TREE
unset RESULT
done
if [ -n "${GIT_STATUSES}" ]; then
echo "/!\ There are some uncommited changes. If you proceed, everything will be commited."
echo "${GIT_STATUSES}"
echo ""
fi
fi
# get input from stdin
echo "> Please, enter details about your maintenance"
read TEXTE
# find out if running in interactive mode, or not
if [ -t 0 ]; then
INTERACTIVE=1
else
INTERACTIVE=0
fi
readonly INTERACTIVE
if [ "${INTERACTIVE}" = "1" ] && [ "${EVOCHECK}" = "1" ]; then
get_evocheck
fi
if [ -n "${GIT_STATUSES}" ] && [ "${INTERACTIVE}" = "1" ]; then
printf "/!\\\ There are some uncommited changes.\n%s\n\n" "${GIT_STATUSES}"
fi
if [ -z "${MESSAGE}" ]; then
if [ "${INTERACTIVE}" = "1" ]; then
printf "> Please, enter details about your maintenance:\n"
fi
read -r MESSAGE
fi
if [ "${TEXTE}" = "" ]; then
if [ -z "${MESSAGE}" ]; then
echo "no value..."
exit 1
fi
# recapitulatif
BLOB=$(cat <<END
Host : $HOSTNAME_TEXT
User : $USER
IP : $IP
Begin : $BEGIN_DATE
End : $END_DATE
Message : $TEXTE
END
)
print_session_data
echo ""
echo "${BLOB}"
echo ""
echo "> Press <Enter> to submit, or <Ctrl+c> to cancel."
read enter
if [ "${INTERACTIVE}" = "1" ] && [ "${AUTO}" = "0" ]; then
if [ "${HOOK_COMMIT}" = "1" ] || [ "${HOOK_MAIL}" = "1" ] || [ "${HOOK_DB}" = "1" ]; then
printf "\nActions to execute:\n"
if [ "${HOOK_COMMIT}" = "1" ]; then
printf "* commit changes in repositories\n"
fi
if [ "${HOOK_MAIL}" = "1" ]; then
printf "* send mail to %s\n" "${EVOMAINTMAIL}"
fi
if [ "${HOOK_DB}" = "1" ]; then
printf "* save metadata to the database\n"
fi
if [ "${HOOK_API}" = "1" ]; then
printf "* send metadata to the API\n"
fi
echo ""
answer=""
while :; do
printf "> Let's continue? [Y,n,i,?] "
read -r answer
case $answer in
[Yy]|"" )
# force "auto" mode, but keep hooks settings
AUTO=1
break
;;
[Nn] )
# force "auto" mode, and disable all hooks
HOOK_COMMIT=0
HOOK_MAIL=0
HOOK_DB=0
HOOK_API=0
AUTO=1
break
;;
[Ii] )
# force "manual" mode
AUTO=0
break
;;
* )
printf "y - yes, execute actions and exit\n"
printf "n - no, don't execute actions and exit\n"
printf "i - switch to interactive mode\n"
printf "? - print this help\n"
;;
esac
done
fi
fi
# write log
echo "----------- $(get_now) ---------------" >> "${LOGFILE}"
echo "${BLOB}" >> "${LOGFILE}"
if [ "${INTERACTIVE}" = "1" ] && [ "${AUTO}" = "0" ]; then
# Commit hook
if [ -n "${GIT_STATUSES}" ] && [ "${HOOK_COMMIT}" = "1" ]; then
printf "/!\ There are some uncommited changes.\n%s\n\n" "${GIT_STATUSES}"
y="Y"; n="n"
answer=""
while :; do
printf "> Do you want to commit the changes? [%s] " "${y},${n}"
read -r answer
case $answer in
[Yy] )
hook_commit;
break
;;
[Nn] )
break
;;
"" )
if [ "${HOOK_COMMIT}" = "1" ]; then
hook_commit
fi
break
;;
* )
echo "answer with a valid choice"
;;
esac
done
fi
# git commit
GIT_COMMITS=""
# Mail hook
if [ "${HOOK_MAIL}" = "1" ]; then
y="Y"; n="n"
else
y="y"; n="N"
fi
answer=""
while :; do
printf "> Do you want to send an email to <%s>? [%s] " "${EVOMAINTMAIL}" "${y},${n},e"
read -r answer
case $answer in
[Yy] )
hook_mail;
break
;;
[Nn] )
break
;;
[Ee] )
printf "> To: [%s] " "${EVOMAINTMAIL}"
read -r mail_recipient
if [ -n "${mail_recipient}" ]; then
EVOMAINTMAIL="${mail_recipient}"
fi
;;
"" )
if [ "${HOOK_MAIL}" = "1" ]; then
hook_mail
fi
break
;;
* )
echo "answer with a valid choice"
;;
esac
done
if test -x "${GIT_BIN}"; then
# loop on possible directories managed by GIT
for dir in ${GIT_REPOSITORIES}; do
# tell Git where to find the repository and the work tree (no need to `cd …` there)
export GIT_DIR="${dir}/.git" GIT_WORK_TREE="${dir}"
# If the repository and the work tree exist, try to commit changes
if test -d "${GIT_DIR}" && test -d "${GIT_WORK_TREE}"; then
CHANGED_LINES=$(${GIT_BIN} status --porcelain | wc -l | tr -d ' ')
if [ "${CHANGED_LINES}" != "0" ]; then
${GIT_BIN} add --all
${GIT_BIN} commit --message "${TEXTE}" --author="${USER} <${USER}@evolix.net>" --quiet
# Add the SHA to the log file if something has been committed
SHA=$(${GIT_BIN} rev-parse --short HEAD)
STATS=$(${GIT_BIN} show --stat | tail -1)
# append commit data, without empty lines
GIT_COMMITS=$(printf "%s\n%s : %s %s" "${GIT_COMMITS}" "${GIT_DIR}" "${SHA}" "${STATS}" | sed -e '/^$/d')
fi
fi
# unset environment variables to prevent accidental influence on other git commands
unset GIT_DIR GIT_WORK_TREE
# Database hook
if [ "${HOOK_DB}" = "1" ]; then
y="Y"; n="n"
else
y="y"; n="N"
fi
answer=""
while :; do
printf "> Do you want to insert your message into the database? [%s] " "${y},${n}"
read -r answer
case $answer in
[Yy] )
hook_db;
break
;;
[Nn] )
break
;;
"" )
if [ "${HOOK_DB}" = "1" ]; then
hook_db
fi
break
;;
* )
echo "answer with a valid choice"
;;
esac
done
if [ -n "${GIT_COMMITS}" ]; then
echo "${GIT_COMMITS}" >> "${LOGFILE}"
# API hook
if [ "${HOOK_API}" = "1" ]; then
y="Y"; n="n"
else
y="y"; n="N"
fi
answer=""
while :; do
printf "> Do you want to send the metadata to the API? [%s] " "${y},${n}"
read -r answer
case $answer in
[Yy] )
hook_api;
break
;;
[Nn] )
break
;;
"" )
if [ "${HOOK_API}" = "1" ]; then
hook_api
fi
break
;;
* )
echo "answer with a valid choice"
;;
esac
done
fi
# insert into PG
# SQL_TEXTE=`echo "${TEXTE}" | sed "s/'/\\\\\\'/g ; s@/@\\\\\/@g ; s@\\&@et@g"`
SQL_TEXTE=`echo "${TEXTE}" | sed "s/'/''/g"`
PG_QUERY="INSERT INTO evomaint(hostname,userid,ipaddress,begin_date,end_date,details) VALUES ('${HOSTNAME}','${USER}','${IP}','${BEGIN_DATE}',now(),'${SQL_TEXTE}')"
echo "${PG_QUERY}" | psql ${PGDB} ${PGTABLE} -h ${PGHOST} --quiet
# Log hook
hook_log
# send mail
MAIL_TEXTE=$(echo "${TEXTE}" | sed -e "s@/@\\\\\/@g ; s@&@\\\\&@")
MAIL_GIT_COMMITS=$(echo "${GIT_COMMITS}" | sed -e "s@/@\\\\\/@g ; s@&@\\\\&@")
cat /usr/share/scripts/evomaintenance.tpl | \
sed -e "s/__TO__/${EVOMAINTMAIL}/ ; s/__HOSTNAME__/${HOSTNAME_TEXT}/ ; s/__USER__/${USER}/ ; s/__BEGIN_DATE__/${BEGIN_DATE}/ ; s/__END_DATE__/${END_DATE}/ ; s/__GIT_COMMITS__/${MAIL_GIT_COMMITS}/ ; s/__TEXTE__/${MAIL_TEXTE}/ ; s/__IP__/${IP}/ ; s/__FULLFROM__/${FULLFROM}/ ; s/__FROM__/${FROM}/ ; s/__URGENCYFROM__/${URGENCYFROM}/ ; s/__URGENCYTEL__/${URGENCYTEL}/" | \
${SENDMAIL_BIN} -oi -t -f ${FROM}
if [ "${INTERACTIVE}" = "0" ] || [ "${AUTO}" = "1" ]; then
if [ "${HOOK_COMMIT}" = "1" ]; then
hook_commit
fi
if [ "${HOOK_MAIL}" = "1" ]; then
hook_mail
fi
if [ "${HOOK_DB}" = "1" ]; then
hook_db
fi
if [ "${HOOK_API}" = "1" ]; then
hook_api
fi
fi
exit 0

@ -0,0 +1,15 @@
# EvoBSD configuration file for newsyslog
#
# logfile_name owner:group mode count size when flags
/var/cron/log root:wheel 600 52 * $W1 Z
/var/log/authlog root:wheel 640 52 * $W1 Z
/var/log/daemon 640 365 * $D0 Z
/var/log/lpd-errs 640 7 * $D0 Z
/var/log/maillog 640 52 * $W1 Z
/var/log/messages 644 365 * $D0 Z
/var/log/secure 600 52 * $W1 Z
/var/log/wtmp 644 52 * $W1 B
/var/log/xferlog 640 7 * $D0 Z
/var/log/pflog 600 30 * $D0 ZB "pkill -HUP -u root -U root -t - -x pflogd"
/var/www/logs/access.log 644 52 * $W1 Z "pkill -USR1 -u root -U root -x httpd"
/var/www/logs/error.log 644 52 * $W1 Z "pkill -USR1 -u root -U root -x httpd"

@ -1,27 +0,0 @@
# $OpenBSD: dot.profile,v 1.9 2010/12/13 12:54:31 millert Exp $
#
# sh/ksh initialization
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/sbin:/usr/local/bin
export PATH HOME TERM
export PS1="\u@\h:\w\\$ "
HISTFILE=$HOME/.histfile
export HISTSIZE=10000
export HISTCONTROL='ignoredups:ignorespace'
export TMOUT=36000
export PAGER=less
umask 022
export ENV='~/.kshrc'
case "$-" in
*i*) # interactive shell
if [ -x /usr/bin/tset ]; then
if [ X"$XTERM_VERSION" = X"" ]; then
eval `/usr/bin/tset -sQ '-munknown:?vt220' $TERM`
else
eval `/usr/bin/tset -IsQ '-munknown:?vt220' $TERM`
fi
fi
;;
esac

@ -9,3 +9,4 @@ set smarttab
set backspace=indent,eol,start
set showcmd
set encoding=utf-8
set mouse=""