Skip to content

Commit 093f46b

Browse files
authored
Handbook: best practices and EOL management (#7583)
New info about the process for EU law compliance: - how to choose an Open Source software - how to create a secure container - how to manage software EOL
1 parent ab792a6 commit 093f46b

File tree

2 files changed

+180
-15
lines changed

2 files changed

+180
-15
lines changed

handbook/best_practices.md

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
---
2+
layout: default
3+
title: Best Practices
4+
nav_order: 7
5+
---
6+
7+
# Best Practices
8+
{: .no_toc }
9+
10+
* TOC
11+
{:toc}
12+
13+
## Selecting Open Source software
14+
15+
### Standing on the shoulders of giants
16+
17+
The phrase "standing on the shoulders of giants" is a metaphor for making progress in any field by building upon the knowledge and discoveries of those who came before. In the context of Open Source, it signifies the collaborative nature of software development where individuals leverage existing codebases and contribute back to the community. This approach allows for faster innovation and the creation of more robust and complex systems.
18+
19+
In Open Source software, this concept is embodied by the very nature of the work. Developers don't start from scratch; they utilize libraries, frameworks, and tools created by others. For example, a web developer might use React (a JavaScript library) or Bootstrap (a CSS framework), both of which are Open Source projects. By building upon these existing foundations, they can create applications more efficiently and with greater functionality.
20+
21+
### Golden rules for selecting Open Source software
22+
23+
When choosing a software, try always to avoid closed source software and prefer Open Source software. Open Source software avoids vendor lock-in, fosters collaboration, and allows for customization to meet specific requirements.
24+
25+
When choosing Open Source software, consider the following golden rules to ensure you make the best decision for your needs:
26+
27+
1. **Check active development**: Verify if the software is actively maintained. Look at the number of contributors, the frequency of commits, and the activity in the issue tracker. An active community is crucial for reporting bugs, receiving help, and contributing pull requests.
28+
29+
2. **Look for backing companies**: While not a guarantee of quality, having a company behind the software often indicates a higher likelihood of long-term support and development, especially if the company generates revenue from the project.
30+
31+
3. **Seek third-party reviews**: Research reviews and opinions about the software on blogs, social media, and other platforms. Independent evaluations can provide valuable insights into the software's strengths and weaknesses.
32+
33+
4. **Evaluate documentation**: Good documentation is essential. It should be comprehensive, up-to-date, and easy to understand, making it easier to adopt and use the software effectively.
34+
35+
5. **Read the code**: If possible, review the source code. Clean, well-structured, and understandable code is a significant advantage, as it makes debugging and extending the software easier.
36+
37+
6. **Check usage statistics**: Look at independent metrics such as GitHub stars, the number of forks, or the volume of discussions on forums and social media. These can indicate the software's popularity and community engagement.
38+
39+
7. **Review security policies**: Ensure the software has a clear policy for updates and security disclosures. This is critical for maintaining a secure and reliable system.
40+
41+
8. **Assess developer engagement**: Developers who participate in conferences and public discussions demonstrate commitment and belief in their project. This is a positive sign of long-term investment.
42+
43+
9. **Test the software**: Try installing and configuring the software. Ease of installation and configuration is a significant plus, as it reduces the time and effort required to get started.
44+
45+
10. **Check license compatibility**: Select a project with a license that is compatible with your intended use. Ensure the license aligns with your organization's legal and operational requirements to avoid potential conflicts.
46+
47+
11. **Consider the project's lifecycle stage**: Evaluate where the project is in its lifecycle. Avoid projects in the "hype" stage unless you are willing to take risks or contribute actively. Mature projects with a stable community and fewer breaking changes are often more dependable.
48+
49+
12. **Assess dependency management**: Be cautious of projects with numerous or unstable dependencies. Fewer dependencies often mean less risk of breakage and easier maintenance.
50+
51+
13. **Perform benchmarks**: If you are considering multiple competing solutions, perform internal benchmarks using your specific use cases and data. This ensures the chosen software meets your performance and functionality requirements.
52+
53+
## Creating secure containers
54+
55+
Creating secure containers is essential to minimize vulnerabilities and ensure the reliability of your applications. Below are some best practices to follow when building container images:
56+
57+
### Prefer rootless containers
58+
59+
Whenever possible, run containers as a non-root user (rootless containers). Rootless containers improve security by reducing the risk of privilege escalation and limiting the impact of potential vulnerabilities. This practice is especially important when deploying containers on NethServer 8 or similar platforms. Ensure that the software you intend to run supports rootless operation, and configure your container runtime accordingly.
60+
61+
### Use multi-stage builds
62+
63+
Multi-stage builds help reduce the size of the final container image by separating the build environment from the runtime environment. This approach ensures that only the necessary artifacts are included in the final image, excluding build tools and dependencies.
64+
65+
For example, when building a Go application:
66+
```Dockerfile
67+
# Stage 1: Build
68+
FROM golang:1.20 AS builder
69+
WORKDIR /app
70+
COPY . .
71+
RUN go build -o myapp
72+
73+
# Stage 2: Runtime
74+
FROM alpine:3.18
75+
WORKDIR /app
76+
COPY --from=builder /app/myapp .
77+
CMD ["./myapp"]
78+
```
79+
80+
### Use minimal base images
81+
82+
Whenever possible, use minimal base images like `Alpine` to reduce the attack surface and the number of vulnerabilities. For example:
83+
84+
```Dockerfile
85+
FROM alpine:3.18
86+
```
87+
However, be cautious when using minimal images, as some software may not be fully compatible with them. For instance, MUSL (used in Alpine) can cause issues with certain applications. In such cases, consider using a more compatible base image like `Debian`,
88+
maybe with the `slim` variant:
89+
90+
```Dockerfile
91+
FROM debian:12.11-slim
92+
```
93+
94+
### Pin image versions
95+
96+
Always specify the version of the base image to ensure consistency and avoid unexpected changes. For example:
97+
```Dockerfile
98+
FROM alpine:3.18
99+
```
100+
Avoid using untagged or `latest` tags, as they can lead to unpredictable builds and runtime issues.
101+
102+
### Consider dependency pinning
103+
104+
When installing packages with managers like `apk` or `apt`, you may choose to pin package versions to improve build reproducibility. For example:
105+
```Dockerfile
106+
RUN apk add --no-cache openssl=3.0.9-r1
107+
```
108+
However, strict pinning can delay important security updates. Weigh the benefits of reproducibility against the need for timely patches, and choose an approach that fits your project's requirements.
109+
110+
### Automate updates with Renovate
111+
112+
Use tools like [Renovate](https://www.mend.io/renovate/) to automate dependency updates. Renovate can create pull requests for updated dependencies, allowing you to review and merge them as needed. This approach ensures that your images stay up-to-date with minimal manual effort.
113+
Renovate default configuration is available at [NethServer/.github](https://github.com/NethServer/.github) repository.
114+
115+
### Analyze image layers with Dive
116+
117+
Use [Dive](https://github.com/wagoodman/dive) to inspect your container images layer by layer. Dive helps visualize changes introduced by each command in your Dockerfile, making it easier to identify unnecessary files, optimize image size, and detect if any secrets or sensitive data have leaked during the build process. Regularly analyzing your images with Dive can lead to more secure and efficient containers.
118+
119+
### Scan images for vulnerabilities with Trivy
120+
121+
Use [Trivy](https://github.com/aquasecurity/trivy) to scan your container images for known vulnerabilities, misconfigurations, and secrets. Trivy supports a wide range of languages and package managers, and can be integrated into your CI/CD pipelines to automate security checks. Regular scans with Trivy help ensure that your images remain secure and compliant with best practices.
122+
123+
### Further reading on reproducible builds
124+
125+
For broader guidance on ensuring your builds are consistent and verifiable, refer to [reproducible-builds.org](https://reproducible-builds.org/). This resource provides best practices and tools for achieving reproducible builds across various environments.
126+
127+
### Implement testing
128+
129+
- **Unit Testing**: At a minimum, create unit tests using the standard testing tools provided by your programming language (e.g., `unittest` for Python, `testing` for Go, etc.). This helps catch issues early and ensures that your code behaves as expected. Automated tests also increase confidence when upgrading dependencies; for example, if Renovate opens a pull request for a minor or patch update and all tests pass, you can safely merge the changes.
130+
- **Test Frameworks**: While NethServer 8 uses [Robot Framework](https://robotframework.org/) for automated testing, each project is free to choose the testing framework that best fits its needs.
131+
132+
### Generate SBOMs
133+
134+
Generate a Software Bill of Materials (SBOM) for your container images to track dependencies and their vulnerabilities. See the [SBOM section in security.md](security.md#sbom-software-bill-of-materials) for more details.
135+
136+
137+
## Repository configuration
138+
139+
All software must be hosted on GitHub under the [NethServer](https://github.com/NethServer) or [Nethesis](https://github.com/Nethesis) organizations.
140+
141+
The GitHub repository configuration should follow some best practices to ensure the same level of security across all products.
142+
Use Renovate for dependency management, while Dependabot only for alerts without automatic pull requests.
143+
144+
Access ``Settings`` -> ``Advanced Security`` then select the following options:
145+
- ``Dependency graph``: enabled
146+
- under Dependency graph section, ``Automatic dependency submission``: disabled
147+
- ``Dependabot alerts``: enabled
148+
- ``Dependabot security updates``: disabled
149+
- ``Grouped security updates``: disabled
150+
- ``Dependabot version updates``: disabled
151+
- ``Dependabot on Actions runners``: enabled
152+
- ``Code scanning``: disabled, feel free to enable it if you want to use it
153+
- ``Secret protection``: disabled, feel free to enable it if you want to use it

handbook/security.md

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@ nav_order: 6
55
---
66

77
# Security
8+
{: .no_toc }
89

910
The [Cyber Resilience Act (CRA)](https://eur-lex.europa.eu/eli/reg/2024/2847/oj) is a regulatory framework established by the European Union to enhance the cybersecurity of digital products and services.
1011
It aims to ensure that manufacturers, developers, and distributors of digital products adhere to stringent security requirements throughout the product lifecycle.
1112
The CRA mandates the implementation of robust security measures, regular updates, and transparent reporting of vulnerabilities to protect consumers and businesses from cyber threats.
1213
CRA is built on existing regulations, such as the General Data Protection Regulation (GDPR), and complements other cybersecurity initiatives, such as the [NIS2 Directive](https://eur-lex.europa.eu/eli/dir/2022/2555).
1314

15+
* TOC
16+
{:toc}
17+
1418
## Essentials cybersecurity requirements
1519

1620
Essential cybersecurity requirements are a set of security measures that must be implemented by manufacturers, developers, and distributors of digital
@@ -106,6 +110,8 @@ And Annex 1, Part 2:
106110

107111
> (5) put in place and enforce a policy on coordinated vulnerability disclosure;
108112
113+
When creating new containers, it's important to minimize the attack surface by following the [container best practices](best_practices.md#creating-secure-containers).
114+
109115
The following guidelines are recommended for managing vulnerabilities on all products.
110116

111117
### Report vulnerabilities
@@ -150,18 +156,24 @@ For software that is not developed by Nethesis but is part of an upstream projec
150156

151157
In both cases, the priority is to address vulnerabilities promptly and ensure the security of users.
152158

153-
## Repository configuration
154-
155-
The repository configuration should follow some best practices to ensure the same level of security across all products.
156-
Use Renovate for dependency management, while Dependabot only for alerts without automatic pull requests.
157-
158-
Access ``Settings`` -> ``Advanced Security`` then select the following options:
159-
- ``Dependency graph``: enabled
160-
- ``Automatic dependency submission``: disabled
161-
- ``Dependabot alerts``: enabled
162-
- ``Dependabot security updates``: disabled
163-
- ``Grouped security updates``: disabled
164-
- ``Dependabot version updates``: disabled
165-
- ``Dependabot on Actions runners``: enabled
166-
- ``Code scanning``: disabled, feel free to enable it if you want to use it
167-
- ``Secret protection``: disabled, feel free to enable it if you want to use it
159+
## Handling End-of-Life (EOL)
160+
161+
Managing End-of-Life (EOL) for software, whether containerized or not, is a critical aspect of maintaining security and functionality. Below are some best practices to handle EOL effectively:
162+
163+
1. **Understand EOL does not imply vulnerabilities**: Software reaching EOL does not automatically mean it has vulnerabilities. However, it does mean that updates and support from the original developers will cease, increasing the risk over time.
164+
165+
2. **Best effort principle**: During the life of the software, developers attempt to update EOL versions when feasible. However, this is not always possible, especially for software relying on outdated libraries that can cause compatibility issues if updated.
166+
167+
3. **Commitment to critical vulnerabilities**: Developers commit to addressing critical and exploitable vulnerabilities, regardless of EOL status. If updates are not possible, mitigations must be documented (see below).
168+
169+
4. **Document mitigations**: When updates are not feasible, ensure that mitigations are clearly documented. This could include steps to isolate the software in a protected environment or other security measures.
170+
Mitigation can be documented in the project manual or README file, ensuring users are aware of the risks and how to manage them.
171+
172+
5. **Use tools to track EOL**: Utilize tools like [endoflife.date](https://endoflife.date/) to monitor the EOL status of software and plan migrations or updates accordingly.
173+
174+
6. **Plan for migration**: Proactively plan for migrating to supported versions or alternative solutions before EOL is reached. This minimizes disruption and ensures continued security and functionality.
175+
176+
## Best practices
177+
178+
When creating software, it is essential to follow best practices to ensure security and maintainability.
179+
Take a look at the [Best practices](best_practices.md) section for more details on how to create secure containers, manage dependencies, and implement testing.

0 commit comments

Comments
 (0)