Skip to content

Commit ba95fce

Browse files
MK8S-25: Use nginx location directives to return 200 for health checks instead of index files
Simplified the approach to fix directory listing security issue by using nginx configuration instead of creating index.html files. Changes: - Updated nginx.conf.j2 to return 200 for root (/) and saltenv paths (/metalk8s-*/) - Removed all index.html file creation from Salt state (installed.sls) - Removed all index.html creation logic from build system (repository.py) - Health checks now pass without requiring any files to be created - Repository files (RPMs, repodata) remain accessible as before - Directory listing is disabled for security This approach eliminates: - Build-time index file creation complexity - Deployment-time file dependencies - Cleanup issues with index files - Timing problems between file creation and container startup The nginx location = / and location = /saltenv/ directives handle health check requests with 200 status, while location / handles all other requests with autoindex off for security.
1 parent 674dbe0 commit ba95fce

File tree

3 files changed

+15
-137
lines changed

3 files changed

+15
-137
lines changed

buildchain/buildchain/targets/repository.py

Lines changed: 0 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ class RPMRepository(Repository):
143143
"""A software repository for CentOS x86_64."""
144144

145145
ARCH = "x86_64"
146-
INDEX_HTML_FILENAME = "index.html"
147146

148147
def __init__(
149148
self,
@@ -208,124 +207,11 @@ def clean() -> None:
208207
task["file_dep"].extend([self.get_rpm_path(pkg) for pkg in self.packages])
209208
return task
210209

211-
def _get_saltenv_directories(self) -> Tuple[Optional[Path], Optional[Path]]:
212-
"""Get saltenv directory paths for scality repository.
213-
214-
Returns:
215-
Tuple of (saltenv_dir, top_saltenv_dir) paths
216-
"""
217-
if self.name != "scality":
218-
return None, None
219-
220-
# Saltenv directory at repository level (cleaner for cleanup)
221-
saltenv_dir = (
222-
self._repo_root
223-
/ self._releasever
224-
/ f"{config.PROJECT_NAME.lower()}-{versions.VERSION}"
225-
)
226-
# Top-level saltenv directory (needed for health check)
227-
top_saltenv_dir = (
228-
self._repo_root / f"{config.PROJECT_NAME.lower()}-{versions.VERSION}"
229-
)
230-
return saltenv_dir, top_saltenv_dir
231-
232-
def _get_index_file_paths(self) -> List[Path]:
233-
"""Get all index.html file paths for this repository.
234-
235-
Returns:
236-
List of all index.html file paths that should be created/cleaned
237-
"""
238-
return [
239-
directory / self.INDEX_HTML_FILENAME
240-
for directory in self._get_repository_directories()
241-
]
242-
243-
def _get_repository_directories(self) -> List[Path]:
244-
"""Get all repository directories that need index.html files.
245-
246-
Returns:
247-
List of directory paths where index.html should be created
248-
"""
249-
# Repository-specific directories
250-
repository_directories = [
251-
self.rootdir, # Repository root (e.g., metalk8s-scality-el8)
252-
self.rootdir / self.ARCH, # Architecture directory (e.g., x86_64)
253-
]
254-
255-
# Add nginx root directory for scality repository
256-
if self.name == "scality":
257-
repository_directories.append(self._repo_root) # /var/www/repositories
258-
259-
# Add saltenv directories for scality repository
260-
saltenv_dir, top_saltenv_dir = self._get_saltenv_directories()
261-
if saltenv_dir and top_saltenv_dir:
262-
repository_directories.extend(
263-
[
264-
# Repository-level saltenv structure
265-
saltenv_dir,
266-
saltenv_dir / "redhat",
267-
saltenv_dir / "redhat" / str(self._releasever),
268-
# Top-level saltenv (for health check)
269-
top_saltenv_dir,
270-
]
271-
)
272-
273-
return repository_directories
274-
275-
def create_index_files(self) -> types.TaskDict:
276-
"""Create index.html files for repository directories."""
277-
278-
def clean() -> None:
279-
"""Delete the index.html files created by this task."""
280-
# Remove the index.html files
281-
for index_file in self._get_index_file_paths():
282-
if index_file.exists():
283-
index_file.unlink()
284-
# Also clean up any empty parent directories that we created
285-
for index_file in self._get_index_file_paths():
286-
parent_dir = index_file.parent
287-
if parent_dir.exists() and not any(parent_dir.iterdir()):
288-
try:
289-
parent_dir.rmdir()
290-
except OSError:
291-
pass # Directory not empty or doesn't exist, ignore
292-
293-
def create_index() -> None:
294-
"""Create empty index.html files in repository directories."""
295-
for index_file in self._get_index_file_paths():
296-
# Create directory if it doesn't exist, then create index.html
297-
index_file.parent.mkdir(parents=True, exist_ok=True)
298-
index_file.touch()
299-
# Set readable permissions for nginx
300-
index_file.chmod(0o644)
301-
302-
# Build targets list using centralized method
303-
targets = self._get_index_file_paths()
304-
305-
task = self.basic_task
306-
task.update(
307-
{
308-
"name": self._get_task_name("create_index_files"),
309-
"actions": [create_index],
310-
"doc": f"Create index.html files for {self.name} repository "
311-
f"directories.",
312-
"title": utils.title_with_target1("CREATE INDEX FILES"),
313-
"targets": targets,
314-
"uptodate": [True],
315-
"verbosity": 0,
316-
"clean": [clean],
317-
"task_dep": [self._get_task_name("build_repodata", with_basename=True)],
318-
}
319-
)
320-
return task
321-
322210
@property
323211
def execution_plan(self) -> List[types.TaskDict]:
324-
"""Override execution plan to include index.html file creation."""
325212
tasks = [self.build_repo()]
326213
if self._packages:
327214
tasks.extend(self.build_packages())
328-
tasks.append(self.create_index_files())
329215
return tasks
330216

331217
def build_packages(self) -> List[types.TaskDict]:

salt/metalk8s/repo/files/nginx.conf.j2

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,24 @@ server {
22
listen {{ listening_address }}:{{ listening_port }};
33
server_name localhost;
44

5+
# Return 200 OK for root path health checks
6+
location = / {
7+
return 200 '';
8+
add_header Content-Type text/plain;
9+
}
10+
11+
# Return 200 OK for saltenv path health checks
12+
{%- for env in archives.keys() %}
13+
location = /{{ env }}/ {
14+
return 200 '';
15+
add_header Content-Type text/plain;
16+
}
17+
{%- endfor %}
18+
519
location / {
620
root /var/www/repositories;
721
# Security fix: Disable directory listing to prevent exposing repository structure
822
autoindex off;
9-
# Serve index.html when directory is accessed
10-
index index.html;
1123
}
1224

1325
include conf.d/*.inc;

salt/metalk8s/repo/installed.sls

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,6 @@ Inject nginx image:
3636
- require:
3737
- sls: metalk8s.container-engine.running
3838
39-
# Create index.html files to prevent directory listing issues
40-
Create repository index files:
41-
file.managed:
42-
- name: /var/lib/metalk8s/repositories/index.html
43-
- contents: ''
44-
- makedirs: True
45-
- mode: '0644'
46-
- require:
47-
- file: Generate repositories nginx configuration
48-
49-
Create saltenv index file:
50-
file.managed:
51-
- name: /var/lib/metalk8s/repositories/{{ saltenv }}/index.html
52-
- contents: ''
53-
- makedirs: True
54-
- mode: '0644'
55-
- require:
56-
- file: Create repository index files
57-
5839
Install repositories manifest:
5940
metalk8s.static_pod_managed:
6041
- name: /etc/kubernetes/manifests/repositories.yaml
@@ -92,7 +73,6 @@ Install repositories manifest:
9273
- file: Generate repositories nginx configuration
9374
- file: Deploy container registry nginx configuration
9475
- file: Generate container registry configuration
95-
- file: Create saltenv index file
9676
9777
Delay after repositories pod deployment:
9878
module.wait:
@@ -121,4 +101,4 @@ Wait for Repositories container to answer:
121101
- status: 200
122102
- request_interval: 1
123103
- require:
124-
- file: Create saltenv index file
104+
- module: Ensure repositories container is up

0 commit comments

Comments
 (0)