Skip to content

Commit edc45f2

Browse files
authored
Merge pull request #9 from errnair/errnair/modernize-selinux-etcbackup-cleanup
Batch 3: SELinux troubleshooting, etcbackup wrapper, and cleanup LGTM
2 parents 5791a7f + 5c9a71b commit edc45f2

File tree

3 files changed

+443
-0
lines changed

3 files changed

+443
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env bash
2+
3+
#################################################
4+
# #
5+
# DEPRECATED - Use install_flask.sh #
6+
# #
7+
#################################################
8+
9+
cat <<'EOF'
10+
╔════════════════════════════════════════════════════════════════╗
11+
║ DEPRECATION NOTICE ║
12+
╚════════════════════════════════════════════════════════════════╝
13+
14+
This script (newuser.sh) has been DEPRECATED and replaced with
15+
modernized alternatives.
16+
17+
REPLACEMENT:
18+
Use: installation_scripts/install_flask.sh
19+
20+
The modernized install_flask.sh script provides:
21+
- Multi-OS support (RHEL/Rocky/AlmaLinux/Ubuntu/Debian)
22+
- Automatic user creation with proper permissions
23+
- Python virtual environment setup
24+
- Gunicorn service configuration
25+
- Nginx integration (optional)
26+
- SELinux configuration
27+
- Firewall configuration
28+
- SSL support with Let's Encrypt
29+
30+
MIGRATION:
31+
Old command:
32+
./newuser.sh myuser
33+
34+
New command:
35+
../../installation_scripts/install_flask.sh
36+
37+
The new script will prompt for username and handle all setup
38+
including webroot, logs, permissions, SELinux contexts, and
39+
Python virtual environment.
40+
41+
DOCUMENTATION:
42+
See: installation_scripts/install_flask.sh --help
43+
Or run without arguments for interactive mode
44+
45+
This deprecated script will be removed in a future release.
46+
EOF
47+
48+
exit 1
Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
#################################################
5+
# #
6+
# SELinux Troubleshooting Tool #
7+
# Diagnose and manage SELinux issues #
8+
# #
9+
#################################################
10+
11+
# Source common library
12+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13+
source "${SCRIPT_DIR}/../lib/common.sh"
14+
15+
# Setup
16+
trap cleanup_on_exit EXIT
17+
require_root
18+
19+
# Configuration
20+
ACTION="${1:-status}"
21+
MODE="${MODE:-temporary}" # temporary or permanent
22+
BACKUP_CONFIG="${BACKUP_CONFIG:-yes}"
23+
24+
print_header "SELinux Troubleshooting Tool"
25+
26+
# Detect OS
27+
OS=$(detect_os)
28+
29+
# Check if SELinux is available
30+
check_selinux_available() {
31+
if ! command_exists getenforce; then
32+
error_exit "SELinux is not available on this system.
33+
34+
This tool requires SELinux-enabled systems (RHEL, CentOS, Fedora, Rocky, AlmaLinux)"
35+
fi
36+
}
37+
38+
# Get current SELinux status
39+
get_selinux_status() {
40+
getenforce 2>/dev/null || echo "Unknown"
41+
}
42+
43+
# Show SELinux status
44+
show_status() {
45+
print_header "SELinux Status"
46+
47+
local current_status=$(get_selinux_status)
48+
49+
echo "Current Mode: $current_status"
50+
echo
51+
sestatus
52+
echo
53+
54+
# Check config file
55+
if [ -f /etc/selinux/config ]; then
56+
print_info "Configuration (/etc/selinux/config):"
57+
grep "^SELINUX=" /etc/selinux/config || echo " No SELINUX setting found"
58+
grep "^SELINUXTYPE=" /etc/selinux/config || echo " No SELINUXTYPE setting found"
59+
fi
60+
}
61+
62+
# Show recent SELinux denials
63+
show_denials() {
64+
print_header "Recent SELinux Denials"
65+
66+
if ! command_exists ausearch; then
67+
print_warning "ausearch not found. Install policycoreutils-python-utils or audit package"
68+
return 1
69+
fi
70+
71+
print_info "Checking for recent SELinux denials (last hour)..."
72+
echo
73+
74+
if ausearch -m AVC,USER_AVC -ts recent 2>/dev/null | grep -q "type=AVC"; then
75+
ausearch -m AVC,USER_AVC -ts recent 2>/dev/null | grep "type=AVC" | head -20
76+
echo
77+
print_info "Use 'ausearch -m AVC -ts recent' for full audit log"
78+
else
79+
print_success "No recent SELinux denials found"
80+
fi
81+
}
82+
83+
# Suggest fixes for SELinux denials
84+
suggest_fixes() {
85+
print_header "SELinux Denial Analysis"
86+
87+
if ! command_exists audit2why; then
88+
print_warning "audit2why not found. Install policycoreutils-python-utils package"
89+
print_info "To install:"
90+
print_info " RHEL/Rocky/AlmaLinux: dnf install policycoreutils-python-utils"
91+
return 1
92+
fi
93+
94+
print_info "Analyzing recent denials and suggesting fixes..."
95+
echo
96+
97+
if ausearch -m AVC,USER_AVC -ts recent 2>/dev/null > /tmp/selinux_denials.log; then
98+
if [ -s /tmp/selinux_denials.log ]; then
99+
audit2why -i /tmp/selinux_denials.log
100+
echo
101+
print_info "To generate a custom policy module:"
102+
print_info " audit2allow -a -M my_policy"
103+
print_info " semodule -i my_policy.pp"
104+
else
105+
print_success "No denials to analyze"
106+
fi
107+
rm -f /tmp/selinux_denials.log
108+
else
109+
print_warning "Could not read audit log. Check audit daemon is running."
110+
fi
111+
}
112+
113+
# Set SELinux to permissive (with warnings)
114+
set_permissive() {
115+
print_header "Setting SELinux to Permissive Mode"
116+
117+
local current_status=$(get_selinux_status)
118+
119+
if [ "$current_status" = "Permissive" ]; then
120+
print_warning "SELinux is already in Permissive mode"
121+
return 0
122+
fi
123+
124+
if [ "$current_status" = "Disabled" ]; then
125+
print_warning "SELinux is Disabled. Cannot set to Permissive without reboot."
126+
print_info "To enable SELinux:"
127+
print_info " 1. Edit /etc/selinux/config and set SELINUX=permissive"
128+
print_info " 2. Reboot the system"
129+
return 1
130+
fi
131+
132+
# Display strong warnings
133+
echo
134+
print_warning "╔════════════════════════════════════════════════════════════════╗"
135+
print_warning "║ SECURITY WARNING ║"
136+
print_warning "╚════════════════════════════════════════════════════════════════╝"
137+
echo
138+
print_warning "Setting SELinux to Permissive mode DISABLES mandatory access controls!"
139+
echo
140+
print_warning "Risks:"
141+
print_warning " - Reduced system security"
142+
print_warning " - Policy violations are logged but NOT enforced"
143+
print_warning " - Compliance violations (PCI-DSS, HIPAA, etc.)"
144+
print_warning " - Not recommended for production systems"
145+
echo
146+
print_info "This should ONLY be used for:"
147+
print_info " - Troubleshooting SELinux issues"
148+
print_info " - Identifying which policies need to be adjusted"
149+
print_info " - Development and testing environments"
150+
echo
151+
print_info "Better alternatives:"
152+
print_info " 1. Use this tool's 'denials' command to see what's blocked"
153+
print_info " 2. Use 'suggest' command to get policy recommendations"
154+
print_info " 3. Create custom SELinux policies instead of disabling"
155+
print_info " 4. Use SELinux booleans: getsebool -a | grep <service>"
156+
print_info " 5. Fix file contexts: restorecon -Rv /path"
157+
echo
158+
159+
# Require confirmation
160+
read -p "Are you sure you want to continue? (Type 'yes' to confirm): " confirm
161+
162+
if [ "$confirm" != "yes" ]; then
163+
print_info "Aborted. No changes made."
164+
return 0
165+
fi
166+
167+
# Determine mode
168+
if [ "$MODE" = "temporary" ]; then
169+
print_info "Setting SELinux to Permissive mode (temporary - reverts on reboot)..."
170+
setenforce 0
171+
print_success "SELinux set to Permissive mode (temporary)"
172+
print_info "This change will revert to Enforcing on next reboot"
173+
else
174+
print_info "Setting SELinux to Permissive mode (permanent)..."
175+
176+
# Backup config
177+
if [ "$BACKUP_CONFIG" = "yes" ]; then
178+
local backup_file="/etc/selinux/config.backup-$(date +%Y%m%d_%H%M%S)"
179+
cp /etc/selinux/config "$backup_file"
180+
print_info "Config backed up to: $backup_file"
181+
fi
182+
183+
# Update config file
184+
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config
185+
sed -i 's/^SELINUX=disabled/SELINUX=permissive/g' /etc/selinux/config
186+
187+
# Set current mode
188+
setenforce 0
189+
190+
print_success "SELinux set to Permissive mode (permanent)"
191+
print_warning "Change is persistent across reboots"
192+
fi
193+
194+
echo
195+
print_info "Current status:"
196+
sestatus | grep "Current mode"
197+
echo
198+
199+
print_info "To re-enable SELinux:"
200+
if [ "$MODE" = "temporary" ]; then
201+
print_info " setenforce 1"
202+
else
203+
print_info " 1. Edit /etc/selinux/config and set SELINUX=enforcing"
204+
print_info " 2. Run: setenforce 1"
205+
print_info " 3. Or reboot"
206+
fi
207+
208+
log_success "SELinux set to Permissive mode (MODE=$MODE)"
209+
}
210+
211+
# Set SELinux to enforcing
212+
set_enforcing() {
213+
print_header "Setting SELinux to Enforcing Mode"
214+
215+
local current_status=$(get_selinux_status)
216+
217+
if [ "$current_status" = "Enforcing" ]; then
218+
print_success "SELinux is already in Enforcing mode"
219+
return 0
220+
fi
221+
222+
if [ "$current_status" = "Disabled" ]; then
223+
print_warning "SELinux is Disabled. Cannot set to Enforcing without reboot."
224+
print_info "To enable SELinux:"
225+
print_info " 1. Edit /etc/selinux/config and set SELINUX=enforcing"
226+
print_info " 2. Reboot the system"
227+
print_info " 3. System will relabel filesystem on first boot (may take time)"
228+
return 1
229+
fi
230+
231+
print_info "Setting SELinux to Enforcing mode..."
232+
233+
# Backup config
234+
if [ "$BACKUP_CONFIG" = "yes" ]; then
235+
local backup_file="/etc/selinux/config.backup-$(date +%Y%m%d_%H%M%S)"
236+
cp /etc/selinux/config "$backup_file"
237+
print_info "Config backed up to: $backup_file"
238+
fi
239+
240+
# Update config file
241+
sed -i 's/^SELINUX=permissive/SELINUX=enforcing/g' /etc/selinux/config
242+
sed -i 's/^SELINUX=disabled/SELINUX=enforcing/g' /etc/selinux/config
243+
244+
# Set current mode
245+
setenforce 1
246+
247+
print_success "SELinux set to Enforcing mode"
248+
echo
249+
sestatus | grep "Current mode"
250+
251+
log_success "SELinux set to Enforcing mode"
252+
}
253+
254+
# Show help
255+
show_help() {
256+
cat <<EOF
257+
SELinux Troubleshooting Tool
258+
259+
Usage: $0 <command> [options]
260+
261+
Commands:
262+
status Show current SELinux status (default)
263+
denials Show recent SELinux denials from audit log
264+
suggest Analyze denials and suggest policy fixes
265+
permissive Set SELinux to Permissive mode (with warnings)
266+
enforcing Set SELinux to Enforcing mode
267+
help Show this help message
268+
269+
Options (environment variables):
270+
MODE=temporary|permanent Mode for permissive/enforcing (default: temporary)
271+
BACKUP_CONFIG=yes|no Backup config before changes (default: yes)
272+
273+
Examples:
274+
$0 status # Show current status
275+
$0 denials # Show recent denials
276+
$0 suggest # Get fix suggestions
277+
$0 permissive # Set permissive (temporary)
278+
MODE=permanent $0 permissive # Set permissive (permanent)
279+
$0 enforcing # Set enforcing
280+
281+
Troubleshooting Workflow:
282+
1. Check status: $0 status
283+
2. View denials: $0 denials
284+
3. Get suggestions: $0 suggest
285+
4. Apply fixes (don't just disable SELinux!)
286+
287+
Common SELinux Fixes:
288+
- Fix file contexts: restorecon -Rv /path/to/files
289+
- Set booleans: setsebool -P httpd_can_network_connect on
290+
- View booleans: getsebool -a | grep httpd
291+
- Custom policy: audit2allow -a -M mypolicy && semodule -i mypolicy.pp
292+
293+
Security Warning:
294+
Disabling or setting SELinux to Permissive reduces system security.
295+
Always prefer fixing SELinux policies over disabling enforcement.
296+
EOF
297+
}
298+
299+
# Main execution
300+
main() {
301+
check_selinux_available
302+
303+
case "$ACTION" in
304+
status)
305+
show_status
306+
;;
307+
denials)
308+
show_denials
309+
;;
310+
suggest|fixes|analyze)
311+
suggest_fixes
312+
;;
313+
permissive)
314+
set_permissive
315+
;;
316+
enforcing)
317+
set_enforcing
318+
;;
319+
help|--help|-h)
320+
show_help
321+
;;
322+
*)
323+
error_exit "Invalid command: $ACTION
324+
325+
Usage: $0 <command>
326+
327+
Commands: status, denials, suggest, permissive, enforcing, help
328+
329+
Run '$0 help' for detailed usage information."
330+
;;
331+
esac
332+
}
333+
334+
# Run main
335+
main

0 commit comments

Comments
 (0)