Compare commits
107 Commits
aws-to-bac
...
master
Author | SHA1 | Date |
---|---|---|
Inex Code | 65b5a19777 | |
Inex Code | 60dd766846 | |
Inex Code | 8006f83257 | |
Inex Code | 74d35b16f2 | |
Inex Code | dd020c3a7d | |
Inex Code | ba1695c642 | |
Inex Code | bc5778fdea | |
Inex Code | 8d99d1c78a | |
Inex Code | 5e64b08381 | |
Inex Code | 7e590ae60c | |
Inex Code | eb36e9b265 | |
Inex Code | 3626506e3a | |
Inex Code | c8c69957b5 | |
Inex Code | 9a8af62e0b | |
Inex Code | a5b965f08f | |
Inex Code | d7edf5a95d | |
Inex Code | bdaf88208f | |
Inex Code | 2e175f8c10 | |
Inex Code | 497cf28ecc | |
Inex Code | 9c662d9629 | |
Inex Code | 0500315ae0 | |
Inex Code | d8f0922b8a | |
Inex Code | ab0c3e113c | |
Inex Code | b4827e6e26 | |
Inex Code | bfe0d18090 | |
Inex Code | 426d84f636 | |
sоvд[сова] | 41edc9f26f | |
sоvд[сова] | 5d3395648a | |
Inex Code | 1944739d28 | |
Inex Code | 08d8407a86 | |
Inex Code | 0d3e8c890c | |
Inex Code | 3dd8ff1821 | |
Inex Code | 895a816ef5 | |
Inex Code | 5210e610df | |
Inex Code | eab3d1e761 | |
Inex Code | a59fbef22a | |
Inex Code | 7a6f57def8 | |
Inex Code | e4ba827d5a | |
Inex Code | aeeffe42b1 | |
Inex Code | 399790e202 | |
Inex Code | 5f2ab0495b | |
Inex Code | 53c9655b7b | |
Inex Code | 52b896da45 | |
Inex Code | 8c81f24fa7 | |
Inex Code | c1ed3a522c | |
NaiJi ✨ | dbb6757d77 | |
NaiJi ✨ | 0c41badf3b | |
NaiJi ✨ | 23e424b841 | |
Inex Code | 67851c7bee | |
Inex Code | 5b4128c010 | |
Inex Code | f6b3c26900 | |
Inex Code | 9d1249d10e | |
Inex Code | ea7572c4e9 | |
Inex Code | a5b57d378d | |
Inex Code | 289b715873 | |
Inex Code | 1a31e32424 | |
Inex Code | cb6378a970 | |
Inex Code | 4bf80d7a2d | |
Inex Code | a0a6c99fe8 | |
Inex Code | 8cb55168eb | |
Illia Chub | 896600bf52 | |
Illia Chub | c03fd25959 | |
Inex Code | b583340e1d | |
Inex Code | dc767677d8 | |
Illia Chub | 163afde7cf | |
Inex Code | d4bb381693 | |
Inex Code | c3ee4d00fc | |
Illia Chub | f5ec301441 | |
Illia Chub | ae8e8b2c9b | |
Illia Chub | b7f49e52c0 | |
Illia Chub | b5011cdd65 | |
Inex Code | 1b8bdb013a | |
Inex Code | 3f42ad5c68 | |
Inex Code | 63aaeec08c | |
Inex Code | 1c1f353ea2 | |
Inex Code | 0e60176b6e | |
Inex Code | bfd2f696a2 | |
Inex Code | 1ba17b61e7 | |
Inex Code | 41cbf0f14e | |
Inex Code | 4c59657fc9 | |
Inex Code | b9d9af01e2 | |
Illia Chub | df2453a6fa | |
Inex Code | 255ea374c0 | |
Inex Code | a71fd79588 | |
Inex Code | 4a17a1e479 | |
Inex Code | 9c2be115f8 | |
Inex Code | 4a0f1db987 | |
Inex Code | e3c81d2a6d | |
Inex Code | 3f9f439c95 | |
Inex Code | cb1940b889 | |
Inex Code | 43833ee918 | |
Inex Code | d38d22a77c | |
Inex Code | 1be64cce4d | |
Inex Code | 2dc389799a | |
Inex Code | bc669579f7 | |
Inex Code | 5ac099afc4 | |
Inex Code | 60f8e77523 | |
Inex Code | 7c2264ff89 | |
Inex Code | e76f0e5d82 | |
Inex Code | 775d64dcb0 | |
Illia Chub | a2704e2717 | |
Inex Code | 8b5865c332 | |
Inex Code | b4bc3a4ffc | |
Inex Code | 18d7a56e96 | |
Inex Code | 3e710e61d2 | |
Inex Code | 0ad5aab4e4 | |
Inex Code | c2da16b16c |
|
@ -1,3 +1,4 @@
|
|||
userdata/userdata.json
|
||||
userdata/tokens.json
|
||||
hardware-configuration.nix
|
||||
networking.nix
|
|
@ -0,0 +1,674 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
10
README.md
10
README.md
|
@ -16,6 +16,10 @@ Example JSON config:
|
|||
"accountKey": "BACKBLAZE_ACCOUNT_KEY",
|
||||
"bucket": "BACKBLAZE_BUCKET_NAME"
|
||||
},
|
||||
"api": {
|
||||
"token": "API_TOKEN",
|
||||
"enableSwagger": false
|
||||
},
|
||||
"bitwarden": {
|
||||
"enable": true
|
||||
},
|
||||
|
@ -52,11 +56,11 @@ Example JSON config:
|
|||
],
|
||||
"passwordAuthentication": true
|
||||
},
|
||||
"username": "owner",
|
||||
"username": "LUSER",
|
||||
"users": [
|
||||
{
|
||||
"hashedPassword": "HASHED_PASSWORD",
|
||||
"username": "LUSER"
|
||||
"hashedPassword": "OTHER_USER_HASHED_PASSWORD",
|
||||
"username": "OTHER_USER"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
with lib;
|
||||
|
||||
let
|
||||
selfprivacy-api = pkgs.callPackage ./api-package.nix { };
|
||||
cfg = config.services.selfprivacy-api;
|
||||
directionArg =
|
||||
if cfg.direction == ""
|
||||
|
@ -13,12 +12,25 @@ in
|
|||
{
|
||||
options.services.selfprivacy-api = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Enable SelfPrivacy API service
|
||||
'';
|
||||
};
|
||||
enableSwagger = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Enable Swagger UI
|
||||
'';
|
||||
};
|
||||
b2Bucket = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
B2 bucket
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
|
@ -28,16 +40,113 @@ in
|
|||
inherit (config.environment.sessionVariables) NIX_PATH;
|
||||
HOME = "/root";
|
||||
PYTHONUNBUFFERED = "1";
|
||||
ENABLE_SWAGGER = (if cfg.enableSwagger then "1" else "0");
|
||||
B2_BUCKET = cfg.b2Bucket;
|
||||
} // config.networking.proxy.envVars;
|
||||
path = [ "/var/" "/var/dkim/" pkgs.coreutils pkgs.gnutar pkgs.xz.bin pkgs.gzip pkgs.gitMinimal config.nix.package.out pkgs.nixos-rebuild pkgs.restic pkgs.mkpasswd ];
|
||||
path = [
|
||||
"/var/"
|
||||
"/var/dkim/"
|
||||
pkgs.coreutils
|
||||
pkgs.gnutar
|
||||
pkgs.xz.bin
|
||||
pkgs.gzip
|
||||
pkgs.gitMinimal
|
||||
config.nix.package.out
|
||||
pkgs.nixos-rebuild
|
||||
pkgs.restic
|
||||
pkgs.mkpasswd
|
||||
pkgs.util-linux
|
||||
pkgs.e2fsprogs
|
||||
pkgs.iproute2
|
||||
];
|
||||
after = [ "network-online.target" ];
|
||||
wantedBy = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
User = "root";
|
||||
ExecStart = "${selfprivacy-api}/bin/app.py";
|
||||
ExecStart = "${pkgs.selfprivacy-graphql-api}/bin/app.py";
|
||||
Restart = "always";
|
||||
RestartSec = "5";
|
||||
};
|
||||
};
|
||||
systemd.services.selfprivacy-api-worker = {
|
||||
description = "Task worker for SelfPrivacy API";
|
||||
environment = config.nix.envVars // {
|
||||
inherit (config.environment.sessionVariables) NIX_PATH;
|
||||
HOME = "/root";
|
||||
PYTHONUNBUFFERED = "1";
|
||||
ENABLE_SWAGGER = (if cfg.enableSwagger then "1" else "0");
|
||||
B2_BUCKET = cfg.b2Bucket;
|
||||
PYTHONPATH = pkgs.selfprivacy-graphql-api.pythonPath + ":${pkgs.selfprivacy-graphql-api}/lib/python3.10/site-packages/";
|
||||
} // config.networking.proxy.envVars;
|
||||
path = [
|
||||
"/var/"
|
||||
"/var/dkim/"
|
||||
pkgs.coreutils
|
||||
pkgs.gnutar
|
||||
pkgs.xz.bin
|
||||
pkgs.gzip
|
||||
pkgs.gitMinimal
|
||||
config.nix.package.out
|
||||
pkgs.nixos-rebuild
|
||||
pkgs.restic
|
||||
pkgs.mkpasswd
|
||||
pkgs.util-linux
|
||||
pkgs.e2fsprogs
|
||||
pkgs.iproute2
|
||||
];
|
||||
after = [ "network-online.target" ];
|
||||
wantedBy = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
User = "root";
|
||||
ExecStart = "${pkgs.python310Packages.huey}/bin/huey_consumer.py selfprivacy_api.task_registry.huey";
|
||||
Restart = "always";
|
||||
RestartSec = "5";
|
||||
};
|
||||
};
|
||||
# One shot systemd service to rebuild NixOS using nixos-rebuild
|
||||
systemd.services.sp-nixos-rebuild = {
|
||||
description = "Upgrade NixOS using nixos-rebuild";
|
||||
environment = config.nix.envVars // {
|
||||
inherit (config.environment.sessionVariables) NIX_PATH;
|
||||
HOME = "/root";
|
||||
} // config.networking.proxy.envVars;
|
||||
path = [ pkgs.coreutils pkgs.gnutar pkgs.xz.bin pkgs.gzip pkgs.gitMinimal config.nix.package.out pkgs.nixos-rebuild ];
|
||||
serviceConfig = {
|
||||
User = "root";
|
||||
ExecStart = "${pkgs.nixos-rebuild}/bin/nixos-rebuild switch";
|
||||
KillMode = "none";
|
||||
SendSIGKILL = "no";
|
||||
};
|
||||
};
|
||||
# One shot systemd service to upgrade NixOS using nixos-rebuild
|
||||
systemd.services.sp-nixos-upgrade = {
|
||||
description = "Upgrade NixOS using nixos-rebuild";
|
||||
environment = config.nix.envVars // {
|
||||
inherit (config.environment.sessionVariables) NIX_PATH;
|
||||
HOME = "/root";
|
||||
} // config.networking.proxy.envVars;
|
||||
path = [ pkgs.coreutils pkgs.gnutar pkgs.xz.bin pkgs.gzip pkgs.gitMinimal config.nix.package.out pkgs.nixos-rebuild ];
|
||||
serviceConfig = {
|
||||
User = "root";
|
||||
ExecStart = "${pkgs.nixos-rebuild}/bin/nixos-rebuild switch --upgrade";
|
||||
KillMode = "none";
|
||||
SendSIGKILL = "no";
|
||||
};
|
||||
};
|
||||
# One shot systemd service to rollback NixOS using nixos-rebuild
|
||||
systemd.services.sp-nixos-rollback = {
|
||||
description = "Rollback NixOS using nixos-rebuild";
|
||||
environment = config.nix.envVars // {
|
||||
inherit (config.environment.sessionVariables) NIX_PATH;
|
||||
HOME = "/root";
|
||||
} // config.networking.proxy.envVars;
|
||||
path = [ pkgs.coreutils pkgs.gnutar pkgs.xz.bin pkgs.gzip pkgs.gitMinimal config.nix.package.out pkgs.nixos-rebuild ];
|
||||
serviceConfig = {
|
||||
User = "root";
|
||||
ExecStart = "${pkgs.nixos-rebuild}/bin/nixos-rebuild switch --rollback";
|
||||
KillMode = "none";
|
||||
SendSIGKILL = "no";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
{ nixpkgs ? import <nixpkgs> { }, pythonPkgs ? nixpkgs.pkgs.python39Packages }:
|
||||
|
||||
let
|
||||
inherit (nixpkgs) pkgs;
|
||||
inherit pythonPkgs;
|
||||
|
||||
selfprivacy-api = { buildPythonPackage, flask, flask-restful, setuptools, portalocker }:
|
||||
buildPythonPackage rec {
|
||||
pname = "selfprivacy-api";
|
||||
version = "1.1";
|
||||
src = builtins.fetchGit {
|
||||
url = "https://git.selfprivacy.org/ilchub/selfprivacy-rest-api.git";
|
||||
rev = "dbb4c1095654bba88d4f0c91b7b195d5262976b6";
|
||||
};
|
||||
propagatedBuildInputs = [ flask flask-restful setuptools portalocker ];
|
||||
meta = {
|
||||
description = ''
|
||||
SelfPrivacy Server Management API
|
||||
'';
|
||||
};
|
||||
};
|
||||
drv = pythonPkgs.callPackage selfprivacy-api { };
|
||||
in
|
||||
if pkgs.lib.inNixShell then drv.env else drv
|
|
@ -1,13 +1,16 @@
|
|||
{ pkgs, ... }:
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
services.selfprivacy-api = {
|
||||
enable = true;
|
||||
enableSwagger = config.services.userdata.api.enableSwagger;
|
||||
b2Bucket = config.services.userdata.backup.bucket;
|
||||
};
|
||||
|
||||
users.users."selfprivacy-api" = {
|
||||
isNormalUser = false;
|
||||
isSystemUser = true;
|
||||
extraGroups = [ "opendkim" ];
|
||||
group = "selfprivacy-api";
|
||||
};
|
||||
users.groups."selfprivacy-api" = {
|
||||
members = [ "selfprivacy-api" ];
|
||||
|
|
|
@ -6,7 +6,7 @@ in
|
|||
services.restic.backups = {
|
||||
options = {
|
||||
passwordFile = "/etc/restic/resticPasswd";
|
||||
repository = "s3:s3.anazonaws.com/${cfg.backblaze.bucket}";
|
||||
repository = "s3:s3.anazonaws.com/${cfg.backup.bucket}";
|
||||
initialize = true;
|
||||
paths = [
|
||||
"/var/dkim"
|
||||
|
@ -24,12 +24,6 @@ in
|
|||
users.users.restic = {
|
||||
isNormalUser = false;
|
||||
isSystemUser = true;
|
||||
group = "restic";
|
||||
};
|
||||
environment.etc."restic/resticPasswd".text = ''
|
||||
${cfg.resticPassword}
|
||||
'';
|
||||
environment.etc."restic/s3Passwd".text = ''
|
||||
AWS_ACCESS_KEY_ID=${cfg.backblaze.accountId}
|
||||
AWS_SECRET_ACCESS_KEY=${cfg.backblaze.accountKey}
|
||||
'';
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
url-overlay = "https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nix-repo/archive/22-11.tar.gz";
|
||||
nix-overlay = (import (builtins.fetchTarball url-overlay));
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
|
||||
./variables-module.nix
|
||||
./variables.nix
|
||||
./vscode.nix
|
||||
./files.nix
|
||||
./volumes.nix
|
||||
./users.nix
|
||||
./mailserver/system/mailserver.nix
|
||||
./mailserver/system/alps.nix
|
||||
./vpn/ocserv.nix
|
||||
./api/api.nix
|
||||
./api/api-module.nix
|
||||
|
@ -26,12 +28,39 @@
|
|||
./git/gitea.nix
|
||||
];
|
||||
|
||||
nixpkgs.overlays = [ (nix-overlay) ];
|
||||
|
||||
services.redis.servers.sp-api = {
|
||||
enable = true;
|
||||
save = [
|
||||
[
|
||||
30
|
||||
1
|
||||
]
|
||||
[
|
||||
10
|
||||
10
|
||||
]
|
||||
];
|
||||
port = 0;
|
||||
settings = {
|
||||
notify-keyspace-events = "KEA";
|
||||
};
|
||||
};
|
||||
|
||||
services.do-agent.enable = if config.services.userdata.server.provider == "DIGITALOCEAN" then true else false;
|
||||
|
||||
boot.cleanTmpDir = true;
|
||||
networking = {
|
||||
hostName = config.services.userdata.hostname;
|
||||
usePredictableInterfaceNames = false;
|
||||
firewall = {
|
||||
allowedTCPPorts = lib.mkForce [ 22 25 80 143 443 465 587 993 8443 ];
|
||||
allowedUDPPorts = lib.mkForce [ 8443 ];
|
||||
allowedTCPPorts = lib.mkForce [ 22 25 80 143 443 465 587 993 4443 8443 ];
|
||||
allowedUDPPorts = lib.mkForce [ 8443 10000 ];
|
||||
extraCommands = ''
|
||||
iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
|
||||
iptables --append FORWARD --in-interface vpn00 -j ACCEPT
|
||||
'';
|
||||
};
|
||||
nameservers = [ "1.1.1.1" "1.0.0.1" ];
|
||||
};
|
||||
|
@ -45,18 +74,22 @@
|
|||
openFirewall = false;
|
||||
};
|
||||
programs.ssh = {
|
||||
pubkeyAcceptedKeyTypes = [ "ssh-ed25519" ];
|
||||
hostKeyAlgorithms = [ "ssh-ed25519" ];
|
||||
pubkeyAcceptedKeyTypes = [ "ssh-ed25519" "ssh-rsa" ];
|
||||
hostKeyAlgorithms = [ "ssh-ed25519" "ssh-rsa" ];
|
||||
};
|
||||
environment.systemPackages = with pkgs; [
|
||||
git
|
||||
jq
|
||||
];
|
||||
environment.variables = {
|
||||
DOMAIN = config.services.userdata.domain;
|
||||
};
|
||||
system.autoUpgrade.enable = true;
|
||||
system.autoUpgrade.allowReboot = false;
|
||||
system.autoUpgrade.channel = https://nixos.org/channels/nixos-21.05-small;
|
||||
system.autoUpgrade = {
|
||||
enable = config.services.userdata.autoUpgrade.enable;
|
||||
allowReboot = config.services.userdata.autoUpgrade.allowReboot;
|
||||
channel = "https://channel.selfprivacy.org/nixos-selfpricacy";
|
||||
};
|
||||
system.stateVersion = config.services.userdata.stateVersion;
|
||||
nix = {
|
||||
optimise.automatic = true;
|
||||
gc = {
|
||||
|
@ -64,6 +97,7 @@
|
|||
options = "--delete-older-than 7d";
|
||||
};
|
||||
};
|
||||
services.journald.extraConfig = "SystemMaxUse=500M";
|
||||
boot.kernel.sysctl = {
|
||||
"net.ipv4.ip_forward" = 1;
|
||||
};
|
||||
|
|
115
files.nix
115
files.nix
|
@ -1,30 +1,107 @@
|
|||
{ config, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.userdata;
|
||||
dnsCredentialsTemplates = {
|
||||
DIGITALOCEAN = "DO_AUTH_TOKEN=REPLACEME";
|
||||
CLOUDFLARE = ''
|
||||
CF_API_KEY=REPLACEME
|
||||
CLOUDFLARE_DNS_API_TOKEN=REPLACEME
|
||||
CLOUDFLARE_ZONE_API_TOKEN=REPLACEME
|
||||
'';
|
||||
DESEC = "DESEC_TOKEN=REPLACEME";
|
||||
};
|
||||
dnsCredentialsTemplate = dnsCredentialsTemplates.${cfg.dns.provider};
|
||||
in
|
||||
{
|
||||
systemd.tmpfiles.rules =
|
||||
let
|
||||
nextcloudDBPass = builtins.replaceStrings [ "\n" "\"" "\\" ] [ "\\n" "\\\"" "\\\\" ] cfg.nextcloud.databasePassword;
|
||||
nextcloudAdminPass = builtins.replaceStrings [ "\n" "\"" "\\" ] [ "\\n" "\\\"" "\\\\" ] cfg.nextcloud.adminPassword;
|
||||
resticPass = builtins.replaceStrings [ "\n" "\"" "\\" ] [ "\\n" "\\\"" "\\\\" ] cfg.resticPassword;
|
||||
domain = builtins.replaceStrings [ "\n" "\"" "\\" ] [ "\\n" "\\\"" "\\\\" ] cfg.domain;
|
||||
cloudflareCredentials = builtins.replaceStrings [ "\n" "\"" "\\" ] [ "\\n" "\\\"" "\\\\" ] ''
|
||||
CF_API_KEY=${cfg.cloudflare.apiKey}
|
||||
CLOUDFLARE_DNS_API_TOKEN=${cfg.cloudflare.apiKey}
|
||||
CLOUDFLARE_ZONE_API_TOKEN=${cfg.cloudflare.apiKey}
|
||||
'';
|
||||
domain = builtins.replaceStrings [ "\n" "\"" "\\" "%" ] [ "\\n" "\\\"" "\\\\" "%%" ] cfg.domain;
|
||||
in
|
||||
[
|
||||
"d /var/restic 0660 restic - - -"
|
||||
"d /var/bitwarden 0777 bitwarden_rs bitwarden_rs -"
|
||||
"d /var/bitwarden/backup 0777 bitwarden_rs bitwarden_rs -"
|
||||
"d /var/lib/pleroma 0600 pleroma pleroma - -"
|
||||
"f /var/lib/pleroma/secrets.exs 0755 pleroma pleroma - -"
|
||||
"f /var/domain 0444 selfprivacy-api selfprivacy-api - ${domain}"
|
||||
"f /var/restic/restic-repo-password 0660 restic - - ${resticPass}"
|
||||
"f /var/nextcloud-db-pass 0440 nextcloud nextcloud - ${nextcloudDBPass}"
|
||||
"f /var/nextcloud-admin-pass 0440 nextcloud nextcloud - ${nextcloudAdminPass}"
|
||||
"f /var/cloudflareCredentials.ini 0440 nginx acmerecievers - ${cloudflareCredentials}"
|
||||
(if cfg.bitwarden.enable then "d /var/lib/bitwarden 0777 vaultwarden vaultwarden -" else "")
|
||||
(if cfg.bitwarden.enable then "d /var/lib/bitwarden/backup 0777 vaultwarden vaultwarden -" else "")
|
||||
(if cfg.pleroma.enable then "d /var/lib/pleroma 0700 pleroma pleroma - -" else "")
|
||||
"d /var/lib/restic 0600 restic - - -"
|
||||
(if cfg.pleroma.enable then "f /var/lib/pleroma/secrets.exs 0755 pleroma pleroma - -" else "")
|
||||
"f+ /var/domain 0444 selfprivacy-api selfprivacy-api - ${domain}"
|
||||
(if cfg.bitwarden.enable then "f /var/lib/bitwarden/.env 0640 vaultwarden vaultwarden - -" else "")
|
||||
];
|
||||
system.activationScripts =
|
||||
let
|
||||
jq = "${pkgs.jq}/bin/jq";
|
||||
sed = "${pkgs.gnused}/bin/sed";
|
||||
in
|
||||
{
|
||||
nextcloudSecrets =
|
||||
if cfg.nextcloud.enable then ''
|
||||
mkdir -p /var/lib/nextcloud
|
||||
cat /etc/nixos/userdata/userdata.json | ${jq} -r '.nextcloud.databasePassword' > /var/lib/nextcloud/db-pass
|
||||
chmod 0440 /var/lib/nextcloud/db-pass
|
||||
chown nextcloud:nextcloud /var/lib/nextcloud/db-pass
|
||||
|
||||
cat /etc/nixos/userdata/userdata.json | ${jq} -r '.nextcloud.adminPassword' > /var/lib/nextcloud/admin-pass
|
||||
chmod 0440 /var/lib/nextcloud/admin-pass
|
||||
chown nextcloud:nextcloud /var/lib/nextcloud/admin-pass
|
||||
''
|
||||
else ''
|
||||
rm -f /var/lib/nextcloud/db-pass
|
||||
rm -f /var/lib/nextcloud/admin-pass
|
||||
'';
|
||||
cloudflareCredentials = ''
|
||||
mkdir -p /var/lib/cloudflare
|
||||
chmod 0440 /var/lib/cloudflare
|
||||
chown nginx:acmerecievers /var/lib/cloudflare
|
||||
echo '${dnsCredentialsTemplate}' > /var/lib/cloudflare/Credentials.ini
|
||||
${sed} -i "s/REPLACEME/$(cat /etc/nixos/userdata/userdata.json | ${jq} -r '.dns.apiKey')/g" /var/lib/cloudflare/Credentials.ini
|
||||
chmod 0440 /var/lib/cloudflare/Credentials.ini
|
||||
chown nginx:acmerecievers /var/lib/cloudflare/Credentials.ini
|
||||
'';
|
||||
resticCredentials = ''
|
||||
mkdir -p /root/.config/rclone
|
||||
chmod 0400 /root/.config/rclone
|
||||
chown root:root /root/.config/rclone
|
||||
echo '[backblaze]' > /root/.config/rclone/rclone.conf
|
||||
echo 'type = b2' >> /root/.config/rclone/rclone.conf
|
||||
echo 'account = REPLACEME1' >> /root/.config/rclone/rclone.conf
|
||||
echo 'key = REPLACEME2' >> /root/.config/rclone/rclone.conf
|
||||
|
||||
${sed} -i "s/REPLACEME1/$(cat /etc/nixos/userdata/userdata.json | ${jq} -r '.backup.accountId')/g" /root/.config/rclone/rclone.conf
|
||||
${sed} -i "s/REPLACEME2/$(cat /etc/nixos/userdata/userdata.json | ${jq} -r '.backup.accountKey')/g" /root/.config/rclone/rclone.conf
|
||||
|
||||
chmod 0400 /root/.config/rclone/rclone.conf
|
||||
chown root:root /root/.config/rclone/rclone.conf
|
||||
|
||||
cat /etc/nixos/userdata/userdata.json | ${jq} -r '.resticPassword' > /var/lib/restic/pass
|
||||
chmod 0400 /var/lib/restic/pass
|
||||
chown restic /var/lib/restic/pass
|
||||
'';
|
||||
pleromaCredentials =
|
||||
if cfg.pleroma.enable then ''
|
||||
echo 'import Config' > /var/lib/pleroma/secrets.exs
|
||||
echo 'config :pleroma, Pleroma.Repo,' >> /var/lib/pleroma/secrets.exs
|
||||
echo ' password: "REPLACEME"' >> /var/lib/pleroma/secrets.exs
|
||||
|
||||
${sed} -i "s/REPLACEME/$(cat /etc/nixos/userdata/userdata.json | ${jq} -r '.databasePassword')/g" /var/lib/pleroma/secrets.exs
|
||||
|
||||
chmod 0750 /var/lib/pleroma/secrets.exs
|
||||
chown pleroma:pleroma /var/lib/pleroma/secrets.exs
|
||||
'' else ''
|
||||
rm -f /var/lib/pleroma/secrets.exs
|
||||
'';
|
||||
bitwardenCredentials =
|
||||
if cfg.bitwarden.enable then ''
|
||||
mkdir -p /var/lib/bitwarden
|
||||
token=$(cat /etc/nixos/userdata/userdata.json | ${jq} -r '.bitwarden.adminToken')
|
||||
if [ "$token" == "null" ]; then
|
||||
# If it's null, delete the contents of the file
|
||||
> /var/lib/bitwarden/.env
|
||||
else
|
||||
echo "ADMIN_TOKEN=$token" > /var/lib/bitwarden/.env
|
||||
fi
|
||||
chmod 0640 /var/lib/bitwarden/.env
|
||||
chown vaultwarden:vaultwarden /var/lib/bitwarden/.env
|
||||
'' else ''
|
||||
rm -f /var/lib/bitwarden/.env
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
{ config, pkgs, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.userdata;
|
||||
in
|
||||
{
|
||||
fileSystems = lib.mkIf cfg.useBinds {
|
||||
"/var/lib/gitea" = {
|
||||
device = "/volumes/${cfg.gitea.location}/gitea";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
};
|
||||
services = {
|
||||
gitea = {
|
||||
enable = cfg.gitea.enable;
|
||||
stateDir = "/var/lib/gitea";
|
||||
log = {
|
||||
rootPath = "/var/lib/gitea/log";
|
||||
level = "Warn";
|
||||
};
|
||||
# log = {
|
||||
# rootPath = "/var/lib/gitea/log";
|
||||
# level = "Warn";
|
||||
# };
|
||||
user = "gitea";
|
||||
database = {
|
||||
type = "sqlite3";
|
||||
|
@ -20,10 +26,10 @@ in
|
|||
path = "/var/lib/gitea/data/gitea.db";
|
||||
createDatabase = true;
|
||||
};
|
||||
ssh = {
|
||||
enable = true;
|
||||
clonePort = 22;
|
||||
};
|
||||
# ssh = {
|
||||
# enable = true;
|
||||
# clonePort = 22;
|
||||
# };
|
||||
lfs = {
|
||||
enable = true;
|
||||
contentDir = "/var/lib/gitea/lfs";
|
||||
|
@ -31,16 +37,17 @@ in
|
|||
appName = "SelfPrivacy git Service";
|
||||
repositoryRoot = "/var/lib/gitea/repositories";
|
||||
domain = "git.${cfg.domain}";
|
||||
rootUrl = "https://${cfg.domain}/";
|
||||
rootUrl = "https://git.${cfg.domain}/";
|
||||
httpAddress = "0.0.0.0";
|
||||
httpPort = 3000;
|
||||
cookieSecure = true;
|
||||
# cookieSecure = true;
|
||||
settings = {
|
||||
mailer = {
|
||||
ENABLED = false;
|
||||
};
|
||||
ui = {
|
||||
DEFAULT_THEME = "arc-green";
|
||||
SHOW_USER_EMAIL = false;
|
||||
};
|
||||
picture = {
|
||||
DISABLE_GRAVATAR = true;
|
||||
|
@ -51,6 +58,13 @@ in
|
|||
repository = {
|
||||
FORCE_PRIVATE = false;
|
||||
};
|
||||
session = {
|
||||
COOKIE_SECURE = true;
|
||||
};
|
||||
log = {
|
||||
ROOT_PATH = "/var/lib/gitea/log";
|
||||
LEVEL = "Warn";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ config, pkgs, ... }:
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
cfg = config.services.userdata;
|
||||
in
|
||||
|
@ -8,14 +8,19 @@ in
|
|||
};
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
email = "${cfg.username}@${cfg.domain}";
|
||||
certs = {
|
||||
defaults = {
|
||||
email = "${cfg.username}@${cfg.domain}";
|
||||
server = if cfg.dns.useStagingACME then "https://acme-staging-v02.api.letsencrypt.org/directory" else "https://acme-v02.api.letsencrypt.org/directory";
|
||||
dnsPropagationCheck = false;
|
||||
reloadServices = [ "nginx" ];
|
||||
};
|
||||
certs = lib.mkForce {
|
||||
"${cfg.domain}" = {
|
||||
domain = "*.${cfg.domain}";
|
||||
extraDomainNames = [ "${cfg.domain}" ];
|
||||
group = "acmerecievers";
|
||||
dnsProvider = "cloudflare";
|
||||
credentialsFile = "/var/cloudflareCredentials.ini";
|
||||
dnsProvider = lib.strings.toLower cfg.dns.provider;
|
||||
credentialsFile = "/var/lib/cloudflare/Credentials.ini";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,11 +12,6 @@ in
|
|||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
"nginx-config-reload" = {
|
||||
serviceConfig = {
|
||||
After = [ "acme-${domain}.service" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
{ lib, fetchgit, buildGoModule, ... }:
|
||||
buildGoModule rec {
|
||||
pname = "alps";
|
||||
version = "v1.0.0"; # latest available tag at the moment
|
||||
|
||||
src = fetchGit {
|
||||
url = "https://git.selfprivacy.org/ilchub/selfprivacy-alps";
|
||||
rev = "dc2109ca2fdabfbda5d924faa4947f5694d5d758";
|
||||
};
|
||||
|
||||
vendorSha256 = "0bqg0qjam4mvh07wfil6l5spz32mk5a7kfxxnwfyva805pzmn6dk";
|
||||
|
||||
deleteVendor = false;
|
||||
runVend = true;
|
||||
|
||||
buildPhase = ''
|
||||
go build ./cmd/alps
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp -r * $out/bin
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "Webmail application for the dovecot/postfix mailserver";
|
||||
homepage = "https://git.selfprivacy.org/ilchub/selfprivacy-alps";
|
||||
license = licenses.mit;
|
||||
};
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
{ pkgs, config, lib, fetchgit, buildGoModule, ... }:
|
||||
let domain = config.services.userdata.domain;
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays =
|
||||
[ (self: super: { alps = self.callPackage ./alps-package.nix { }; }) ];
|
||||
|
||||
systemd.services = {
|
||||
alps = {
|
||||
path = [ pkgs.alps pkgs.coreutils ];
|
||||
serviceConfig = {
|
||||
ExecStart =
|
||||
"${pkgs.alps}/bin/alps -theme sourcehut imaps://${domain}:993 smtps://${domain}:465";
|
||||
WorkingDirectory = "${pkgs.alps}/bin";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -6,16 +6,22 @@ in
|
|||
imports = [
|
||||
(builtins.fetchTarball {
|
||||
# Pick a commit from the branch you are interested in
|
||||
url = "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/5675b122/nixos-mailserver-5675b122.tar.gz";
|
||||
url = "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/6d0d9fb9/nixos-mailserver-6d0d9fb9.tar.gz";
|
||||
|
||||
# And set its hash
|
||||
sha256 = "1fwhb7a5v9c98nzhf3dyqf3a5ianqh7k50zizj8v5nmj3blxw4pi";
|
||||
sha256 = "sha256:0h35al73p15z9v8zb6hi5nq987sfl5wp4rm5c8947nlzlnsjl61x";
|
||||
})
|
||||
];
|
||||
|
||||
services.dovecot2 = {
|
||||
enablePAM = lib.mkForce true;
|
||||
showPAMFailure = lib.mkForce true;
|
||||
fileSystems = lib.mkIf cfg.useBinds {
|
||||
"/var/vmail" = {
|
||||
device = "/volumes/${cfg.email.location}/vmail";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
"/var/sieve" = {
|
||||
device = "/volumes/${cfg.email.location}/sieve";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
};
|
||||
|
||||
users.users = {
|
||||
|
@ -34,11 +40,10 @@ in
|
|||
loginAccounts = {
|
||||
"${cfg.username}@${cfg.domain}" = {
|
||||
hashedPassword = cfg.hashedMasterPassword;
|
||||
catchAll = [ cfg.domain ];
|
||||
sieveScript = ''
|
||||
require ["fileinto", "mailbox"];
|
||||
if header :contains "Chat-Version" "1.0"
|
||||
{
|
||||
{
|
||||
fileinto :create "DeltaChat";
|
||||
stop;
|
||||
}
|
||||
|
@ -49,11 +54,10 @@ in
|
|||
name = "${user.username}@${cfg.domain}";
|
||||
value = {
|
||||
hashedPassword = user.hashedPassword;
|
||||
catchAll = [ cfg.domain ];
|
||||
sieveScript = ''
|
||||
require ["fileinto", "mailbox"];
|
||||
if header :contains "Chat-Version" "1.0"
|
||||
{
|
||||
{
|
||||
fileinto :create "DeltaChat";
|
||||
stop;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
{ pkgs, config, ... }:
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
cfg = config.services.userdata;
|
||||
in
|
||||
{
|
||||
fileSystems = lib.mkIf cfg.useBinds {
|
||||
"/var/lib/nextcloud" = {
|
||||
device = "/volumes/${cfg.nextcloud.location}/nextcloud";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
};
|
||||
services.nextcloud = {
|
||||
enable = cfg.nextcloud.enable;
|
||||
package = pkgs.nextcloud22;
|
||||
package = pkgs.nextcloud25;
|
||||
hostName = "cloud.${cfg.domain}";
|
||||
|
||||
# Use HTTPS for links
|
||||
|
@ -18,16 +24,16 @@ in
|
|||
|
||||
config = {
|
||||
# Further forces Nextcloud to use HTTPS
|
||||
overwriteProtocol = "http";
|
||||
overwriteProtocol = "https";
|
||||
|
||||
# Nextcloud PostegreSQL database configuration, recommended over using SQLite
|
||||
dbtype = "sqlite";
|
||||
dbuser = "nextcloud";
|
||||
dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
|
||||
dbname = "nextcloud";
|
||||
dbpassFile = "/var/nextcloud-db-pass";
|
||||
dbpassFile = "/var/lib/nextcloud/db-pass";
|
||||
|
||||
adminpassFile = "/var/nextcloud-admin-pass";
|
||||
adminpassFile = "/var/lib/nextcloud/admin-pass";
|
||||
adminuser = "admin";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,12 +1,23 @@
|
|||
{ pkgs, config, ... }:
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
cfg = config.services.userdata;
|
||||
in
|
||||
{
|
||||
services.bitwarden_rs = {
|
||||
fileSystems = lib.mkIf cfg.useBinds {
|
||||
"/var/lib/bitwarden" = {
|
||||
device = "/volumes/${cfg.bitwarden.location}/bitwarden";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
"/var/lib/bitwarden_rs" = {
|
||||
device = "/volumes/${cfg.bitwarden.location}/bitwarden_rs";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
};
|
||||
services.vaultwarden = {
|
||||
enable = cfg.bitwarden.enable;
|
||||
dbBackend = "sqlite";
|
||||
backupDir = "/var/bitwarden/backup";
|
||||
backupDir = "/var/lib/bitwarden/backup";
|
||||
environmentFile = "/var/lib/bitwarden/.env";
|
||||
config = {
|
||||
domain = "https://password.${cfg.domain}/";
|
||||
signupsAllowed = true;
|
||||
|
|
|
@ -22,9 +22,8 @@ config :pleroma, :media_proxy,
|
|||
config :pleroma, Pleroma.Repo,
|
||||
adapter: Ecto.Adapters.Postgres,
|
||||
username: "pleroma",
|
||||
password: "$DB_PASSWORD",
|
||||
database: "pleroma",
|
||||
hostname: "localhost",
|
||||
socket_dir: "/run/postgresql",
|
||||
pool_size: 10
|
||||
|
||||
#config :web_push_encryption, :vapid_details,
|
||||
|
@ -41,4 +40,4 @@ config :pleroma, :http_security,
|
|||
|
||||
#config :joken, default_signer: ""
|
||||
|
||||
config :pleroma, configurable_from_database: false
|
||||
config :pleroma, configurable_from_database: true
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
{ config, options, lib, pkgs, stdenv, ... }:
|
||||
let
|
||||
cfg = config.services.pleroma;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.pleroma = with lib; {
|
||||
enable = mkEnableOption "pleroma";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.pleroma-otp;
|
||||
description = "Pleroma package to use.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "pleroma";
|
||||
description = "User account under which pleroma runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "pleroma";
|
||||
description = "Group account under which pleroma runs.";
|
||||
};
|
||||
|
||||
stateDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/pleroma";
|
||||
readOnly = true;
|
||||
description = "Directory where the pleroma service will save the uploads and static files.";
|
||||
};
|
||||
|
||||
configs = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = ''
|
||||
Pleroma public configuration.
|
||||
This list gets appended from left to
|
||||
right into /etc/pleroma/config.exs. Elixir evaluates its
|
||||
configuration imperatively, meaning you can override a
|
||||
setting by appending a new str to this NixOS option list.
|
||||
<emphasis>DO NOT STORE ANY PLEROMA SECRET
|
||||
HERE</emphasis>, use
|
||||
<link linkend="opt-services.pleroma.secretConfigFile">services.pleroma.secretConfigFile</link>
|
||||
instead.
|
||||
This setting is going to be stored in a file part of
|
||||
the Nix store. The Nix store being world-readable, it's not
|
||||
the right place to store any secret
|
||||
Have a look to Pleroma section in the NixOS manual for more
|
||||
informations.
|
||||
'';
|
||||
};
|
||||
|
||||
secretConfigFile = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/pleroma/secrets.exs";
|
||||
description = ''
|
||||
Path to the file containing your secret pleroma configuration.
|
||||
<emphasis>DO NOT POINT THIS OPTION TO THE NIX
|
||||
STORE</emphasis>, the store being world-readable, it'll
|
||||
compromise all your secrets.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users = {
|
||||
users."${cfg.user}" = {
|
||||
description = "Pleroma user";
|
||||
home = cfg.stateDir;
|
||||
extraGroups = [ cfg.group ];
|
||||
};
|
||||
groups."${cfg.group}" = { };
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
environment.etc."/pleroma/config.exs".text = ''
|
||||
${lib.concatMapStrings (x: "${x}") cfg.configs}
|
||||
# The lau/tzdata library is trying to download the latest
|
||||
# timezone database in the OTP priv directory by default.
|
||||
# This directory being in the store, it's read-only.
|
||||
# Setting that up to a more appropriate location.
|
||||
config :tzdata, :data_dir, "/var/lib/pleroma/elixir_tzdata_data"
|
||||
import_config "${cfg.secretConfigFile}"
|
||||
'';
|
||||
|
||||
systemd.services.pleroma = {
|
||||
description = "Pleroma social network";
|
||||
after = [ "network-online.target" "postgresql.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ config.environment.etc."/pleroma/config.exs".source ];
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
Type = "exec";
|
||||
WorkingDirectory = "~";
|
||||
StateDirectory = "pleroma pleroma/static pleroma/uploads";
|
||||
StateDirectoryMode = "700";
|
||||
|
||||
# Checking the conf file is there then running the database
|
||||
# migration before each service start, just in case there are
|
||||
# some pending ones.
|
||||
#
|
||||
# It's sub-optimal as we'll always run this, even if pleroma
|
||||
# has not been updated. But the no-op process is pretty fast.
|
||||
# Better be safe than sorry migration-wise.
|
||||
ExecStartPre =
|
||||
let preScript = pkgs.writers.writeBashBin "pleromaStartPre"
|
||||
"${cfg.package}/bin/pleroma_ctl migrate";
|
||||
in "${preScript}/bin/pleromaStartPre";
|
||||
|
||||
ExecStart = "${cfg.package}/bin/pleroma start";
|
||||
ExecStop = "${cfg.package}/bin/pleroma stop";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
|
||||
# Systemd sandboxing directives.
|
||||
# Taken from the upstream contrib systemd service at
|
||||
# pleroma/installation/pleroma.service
|
||||
PrivateTmp = true;
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "full";
|
||||
PrivateDevices = false;
|
||||
NoNewPrivileges = true;
|
||||
CapabilityBoundingSet = "~CAP_SYS_ADMIN";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
meta.maintainers = with lib.maintainers; [ ninjatrappeur ];
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, autoPatchelfHook
|
||||
, fetchurl
|
||||
, file
|
||||
, makeWrapper
|
||||
, ncurses
|
||||
, nixosTests
|
||||
, openssl
|
||||
, unzip
|
||||
, zlib
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "pleroma-otp";
|
||||
version = "2.3.0";
|
||||
|
||||
# To find the latest binary release stable link, have a look at
|
||||
# the CI pipeline for the latest commit of the stable branch
|
||||
# https://git.pleroma.social/pleroma/pleroma/-/tree/stable
|
||||
src = {
|
||||
aarch64-linux = fetchurl {
|
||||
url = "https://git.pleroma.social/pleroma/pleroma/-/jobs/182392/artifacts/download";
|
||||
sha256 = "1drpd6xh7m2damxi5impb8jwvjl6m3qv5yxynl12i8g66vi3rbwf";
|
||||
};
|
||||
x86_64-linux = fetchurl {
|
||||
url = "https://git.pleroma.social/pleroma/pleroma/-/jobs/182388/artifacts/download";
|
||||
sha256 = "1c6l04gga9iigm249ywwcrjg6wzy8iiid652mws3j9dnl71w2sim";
|
||||
};
|
||||
}."${stdenv.hostPlatform.system}";
|
||||
|
||||
nativeBuildInputs = [ unzip ];
|
||||
|
||||
buildInputs = [
|
||||
autoPatchelfHook
|
||||
file
|
||||
makeWrapper
|
||||
ncurses
|
||||
openssl
|
||||
zlib
|
||||
];
|
||||
|
||||
# mkDerivation fails to detect the zip nature of $src due to the
|
||||
# missing .zip extension.
|
||||
# Let's unpack the archive explicitely.
|
||||
unpackCmd = "unzip $curSrc";
|
||||
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
cp -r * $out'';
|
||||
|
||||
# Pleroma is using the project's root path (here the store path)
|
||||
# as its TMPDIR.
|
||||
# Patching it to move the tmp dir to the actual tmpdir
|
||||
postFixup = ''
|
||||
wrapProgram $out/bin/pleroma --set-default RELEASE_TMP "/tmp"
|
||||
wrapProgram $out/bin/pleroma_ctl --set-default RELEASE_TMP "/tmp"'';
|
||||
|
||||
passthru.tests = {
|
||||
pleroma = nixosTests.pleroma;
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "ActivityPub microblogging server";
|
||||
homepage = https://git.pleroma.social/pleroma/pleroma;
|
||||
license = licenses.agpl3;
|
||||
maintainers = with maintainers; [ ninjatrappeur ];
|
||||
platforms = [ "x86_64-linux" "aarch64-linux" ];
|
||||
};
|
||||
}
|
|
@ -1,33 +1,49 @@
|
|||
{ pkgs, config, ... }:
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
cfg = config.services.userdata;
|
||||
in
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
pleroma-otp = self.callPackage ./pleroma-package.nix { };
|
||||
})
|
||||
];
|
||||
fileSystems = lib.mkIf cfg.useBinds {
|
||||
"/var/lib/pleroma" = {
|
||||
device = "/volumes/${cfg.pleroma.location}/pleroma";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
"/var/lib/postgresql" = {
|
||||
device = "/volumes/${cfg.pleroma.location}/postgresql";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
};
|
||||
services = {
|
||||
pleroma = {
|
||||
enable = cfg.pleroma.enable;
|
||||
user = "pleroma";
|
||||
group = "pleroma";
|
||||
configs = [
|
||||
builtins.replaceStrings
|
||||
[ "$DOMAIN" "$LUSER" "$DB_PASSWORD" ]
|
||||
[ cfg.domain cfg.username cfg.databasePassword ]
|
||||
(builtins.readFile ./config.exs)
|
||||
(builtins.replaceStrings
|
||||
[ "$DOMAIN" "$LUSER" ]
|
||||
[ cfg.domain cfg.username ]
|
||||
(builtins.readFile ./config.exs))
|
||||
];
|
||||
};
|
||||
postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_12;
|
||||
initialScript = "/etc/setup.psql";
|
||||
ensureDatabases = [
|
||||
"pleroma"
|
||||
];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "pleroma";
|
||||
ensurePermissions = {
|
||||
"DATABASE pleroma" = "ALL PRIVILEGES";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
environment.etc."setup.psql".text = ''
|
||||
CREATE USER pleroma WITH ENCRYPTED PASSWORD '${cfg.databasePassword}';
|
||||
CREATE USER pleroma;
|
||||
CREATE DATABASE pleroma OWNER pleroma;
|
||||
\c pleroma;
|
||||
--Extensions made by ecto.migrate that need superuser access
|
||||
|
@ -39,5 +55,6 @@ in
|
|||
extraGroups = [ "postgres" ];
|
||||
isNormalUser = false;
|
||||
isSystemUser = true;
|
||||
group = "pleroma";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,6 +3,17 @@
|
|||
"$id": "https://git.selfprivacy.org/inex/selfprivacy-nixos-config/raw/branch/master/userdata/schema.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"autoUpgrade": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"allowReboot": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -15,9 +26,32 @@
|
|||
"hashedMasterPassword": {
|
||||
"type": "string"
|
||||
},
|
||||
"sshKeys": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"timezone": {
|
||||
"type": "string"
|
||||
},
|
||||
"api": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"enableSwagger": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"skippedMigrations": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"backblaze": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/schema#",
|
||||
"$id": "https://git.selfprivacy.org/inex/selfprivacy-nixos-config/raw/branch/master/userdata/tokens_schema.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tokens": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"date": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"token",
|
||||
"name",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
},
|
||||
"recovery_token": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"date": {
|
||||
"type": "string"
|
||||
},
|
||||
"expiration": {
|
||||
"type": "string"
|
||||
},
|
||||
"uses_left": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"token",
|
||||
"date"
|
||||
]
|
||||
},
|
||||
"new_device": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"date": {
|
||||
"type": "string"
|
||||
},
|
||||
"expiration": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"token",
|
||||
"date",
|
||||
"expiration"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"tokens"
|
||||
]
|
||||
}
|
|
@ -9,6 +9,7 @@ in
|
|||
"${cfg.username}" = {
|
||||
isNormalUser = true;
|
||||
hashedPassword = cfg.hashedMasterPassword;
|
||||
openssh.authorizedKeys.keys = cfg.sshKeys;
|
||||
};
|
||||
} // builtins.listToAttrs (builtins.map
|
||||
(user: {
|
||||
|
@ -16,6 +17,7 @@ in
|
|||
value = {
|
||||
isNormalUser = true;
|
||||
hashedPassword = user.hashedPassword;
|
||||
openssh.authorizedKeys.keys = (if user ? sshKeys then user.sshKeys else [ ]);
|
||||
};
|
||||
})
|
||||
cfg.users);
|
||||
|
|
|
@ -11,86 +11,146 @@ let
|
|||
in
|
||||
{
|
||||
options.services.userdata = {
|
||||
enable = mkOption {
|
||||
default = true;
|
||||
type = types.nullOr types.bool;
|
||||
};
|
||||
# General server options
|
||||
hostname = mkOption {
|
||||
description = "The hostname of the server.";
|
||||
type = types.nullOr types.string;
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
domain = mkOption {
|
||||
description = ''
|
||||
Domain used by the server
|
||||
'';
|
||||
type = types.nullOr types.string;
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
timezone = mkOption {
|
||||
description = ''
|
||||
Timezone used by the server
|
||||
'';
|
||||
type = types.nullOr types.str;
|
||||
default = "Europe/Uzhgorod";
|
||||
};
|
||||
autoUpgrade = {
|
||||
enable = mkOption {
|
||||
description = "Enable auto-upgrade of the server.";
|
||||
default = true;
|
||||
type = types.nullOr types.bool;
|
||||
};
|
||||
allowReboot = mkOption {
|
||||
description = "Allow the server to reboot during the upgrade.";
|
||||
default = false;
|
||||
type = types.nullOr types.bool;
|
||||
};
|
||||
};
|
||||
stateVersion = mkOption {
|
||||
description = ''
|
||||
State version of the server
|
||||
'';
|
||||
type = types.str;
|
||||
default = "22.11";
|
||||
};
|
||||
########################
|
||||
# Server admin options #
|
||||
########################
|
||||
username = mkOption {
|
||||
description = ''
|
||||
Username that was defined at the initial setup process
|
||||
'';
|
||||
type = types.nullOr types.string;
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
hashedMasterPassword = mkOption {
|
||||
description = ''
|
||||
Hash of the password that was defined at the initial setup process
|
||||
'';
|
||||
type = types.nullOr types.string;
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
backblaze = {
|
||||
sshKeys = mkOption {
|
||||
description = ''
|
||||
SSH keys of the user that was defined at the initial setup process
|
||||
'';
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = [ ];
|
||||
};
|
||||
###############
|
||||
# API options #
|
||||
###############
|
||||
api = {
|
||||
enableSwagger = mkOption {
|
||||
default = true;
|
||||
description = ''
|
||||
Enable Swagger UI
|
||||
'';
|
||||
type = types.bool;
|
||||
};
|
||||
skippedMigrations = mkOption {
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of migrations that should be skipped
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
};
|
||||
#############
|
||||
# Secrets #
|
||||
#############
|
||||
dns = {
|
||||
provider = mkOption {
|
||||
description = "DNS provider that was defined at the initial setup process. Default is ClOUDFLARE";
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
useStagingACME = mkOption {
|
||||
description = "Use staging ACME server. Default is false";
|
||||
type = types.nullOr types.bool;
|
||||
};
|
||||
};
|
||||
backup = {
|
||||
bucket = mkOption {
|
||||
description = "Bucket name used for userdata backups";
|
||||
type = types.nullOr types.string;
|
||||
};
|
||||
accountId = mkOption {
|
||||
description = "Backblaze B2 Account ID";
|
||||
type = types.nullOr types.string;
|
||||
};
|
||||
accountKey = mkOption {
|
||||
description = "Backblaze B2 Account Key.";
|
||||
type = types.nullOr types.string;
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
};
|
||||
cloudflare = {
|
||||
apiKey = mkOption {
|
||||
description = "Cloudflare API Key.";
|
||||
type = types.nullOr types.string;
|
||||
server = {
|
||||
provider = mkOption {
|
||||
description = "Server provider that was defined at the initial setup process. Default is HETZNER";
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
};
|
||||
databasePassword = mkOption {
|
||||
description = ''
|
||||
Password for the database
|
||||
'';
|
||||
type = types.nullOr types.string;
|
||||
};
|
||||
##############
|
||||
# Services #
|
||||
##############
|
||||
bitwarden = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.nullOr types.bool;
|
||||
};
|
||||
location = mkOption {
|
||||
default = "sda1";
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
};
|
||||
email = {
|
||||
location = mkOption {
|
||||
default = "sda1";
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
};
|
||||
gitea = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
type = types.nullOr types.bool;
|
||||
};
|
||||
location = mkOption {
|
||||
default = "sda1";
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
};
|
||||
nextcloud = {
|
||||
enable = mkOption {
|
||||
default = true;
|
||||
type = types.nullOr types.bool;
|
||||
};
|
||||
databasePassword = mkOption {
|
||||
description = ''
|
||||
Password for the nextcloud database
|
||||
'';
|
||||
type = types.nullOr types.string;
|
||||
};
|
||||
adminPassword = mkOption {
|
||||
description = ''
|
||||
Password for the nextcloud admin user
|
||||
'';
|
||||
type = types.nullOr types.string;
|
||||
location = mkOption {
|
||||
default = "sda1";
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
};
|
||||
pleroma = {
|
||||
|
@ -98,6 +158,10 @@ in
|
|||
default = false;
|
||||
type = types.nullOr types.bool;
|
||||
};
|
||||
location = mkOption {
|
||||
default = "sda1";
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
};
|
||||
jitsi = {
|
||||
enable = mkOption {
|
||||
|
@ -111,12 +175,9 @@ in
|
|||
type = types.nullOr types.bool;
|
||||
};
|
||||
};
|
||||
resticPassword = mkOption {
|
||||
description = ''
|
||||
Password for the restic
|
||||
'';
|
||||
type = types.nullOr types.string;
|
||||
};
|
||||
#########
|
||||
# SSH #
|
||||
#########
|
||||
ssh = {
|
||||
enable = mkOption {
|
||||
default = true;
|
||||
|
@ -124,9 +185,10 @@ in
|
|||
};
|
||||
rootKeys = mkOption {
|
||||
description = ''
|
||||
Root SSH Keys
|
||||
Root SSH Keys
|
||||
'';
|
||||
type = types.nullOr (types.listOf types.string);
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = [ "" ];
|
||||
};
|
||||
passwordAuthentication = mkOption {
|
||||
description = ''
|
||||
|
@ -136,18 +198,29 @@ in
|
|||
type = types.nullOr types.bool;
|
||||
};
|
||||
};
|
||||
timezone = mkOption {
|
||||
description = ''
|
||||
Timezone used by the server
|
||||
'';
|
||||
type = types.nullOr types.string;
|
||||
default = "Europe/Uzhgorod";
|
||||
};
|
||||
###########
|
||||
# Users #
|
||||
###########
|
||||
users = mkOption {
|
||||
description = ''
|
||||
Users that will be created on the server
|
||||
'';
|
||||
type = types.nullOr (types.listOf (types.attrsOf types.anything));
|
||||
default = [ ];
|
||||
};
|
||||
##############
|
||||
# Volumes #
|
||||
##############
|
||||
volumes = mkOption {
|
||||
description = ''
|
||||
Volumes that will be created on the server
|
||||
'';
|
||||
type = types.nullOr (types.listOf (types.attrsOf types.anything));
|
||||
default = [ ];
|
||||
};
|
||||
useBinds = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,66 @@
|
|||
{ pkgs, ... }:
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
jsonData = builtins.fromJSON (builtins.readFile ./userdata/userdata.json);
|
||||
in
|
||||
{
|
||||
services = {
|
||||
userdata = builtins.fromJSON (builtins.readFile ./userdata/userdata.json);
|
||||
services.userdata = {
|
||||
hostname = lib.attrsets.attrByPath [ "hostname" ] null jsonData;
|
||||
domain = lib.attrsets.attrByPath [ "domain" ] null jsonData;
|
||||
timezone = lib.attrsets.attrByPath [ "timezone" ] "Europe/Uzhgorod" jsonData;
|
||||
stateVersion = lib.attrsets.attrByPath [ "stateVersion" ] "22.05" jsonData;
|
||||
autoUpgrade = {
|
||||
enable = lib.attrsets.attrByPath [ "autoUpgrade" "enable" ] true jsonData;
|
||||
allowReboot = lib.attrsets.attrByPath [ "autoUpgrade" "allowReboot" ] true jsonData;
|
||||
};
|
||||
username = lib.attrsets.attrByPath [ "username" ] null jsonData;
|
||||
hashedMasterPassword = lib.attrsets.attrByPath [ "hashedMasterPassword" ] null jsonData;
|
||||
sshKeys = lib.attrsets.attrByPath [ "sshKeys" ] [ ] jsonData;
|
||||
api = {
|
||||
enableSwagger = lib.attrsets.attrByPath [ "api" "enableSwagger" ] false jsonData;
|
||||
skippedMigrations = lib.attrsets.attrByPath [ "api" "skippedMigrations" ] [ ] jsonData;
|
||||
};
|
||||
dns = {
|
||||
provider = lib.attrsets.attrByPath [ "dns" "provider" ] "CLOUDFLARE" jsonData;
|
||||
useStagingACME = lib.attrsets.attrByPath [ "dns" "useStagingACME" ] false jsonData;
|
||||
};
|
||||
backup = {
|
||||
bucket = lib.attrsets.attrByPath [ "backup" "bucket" ] (lib.attrsets.attrByPath [ "backblaze" "bucket" ] "" jsonData) jsonData;
|
||||
};
|
||||
server = {
|
||||
provider = lib.attrsets.attrByPath [ "server" "provider" ] "HETZNER" jsonData;
|
||||
};
|
||||
bitwarden = {
|
||||
enable = lib.attrsets.attrByPath [ "bitwarden" "enable" ] false jsonData;
|
||||
location = lib.attrsets.attrByPath [ "bitwarden" "location" ] "sda1" jsonData;
|
||||
};
|
||||
gitea = {
|
||||
enable = lib.attrsets.attrByPath [ "gitea" "enable" ] false jsonData;
|
||||
location = lib.attrsets.attrByPath [ "gitea" "location" ] "sda1" jsonData;
|
||||
};
|
||||
nextcloud = {
|
||||
enable = lib.attrsets.attrByPath [ "nextcloud" "enable" ] false jsonData;
|
||||
location = lib.attrsets.attrByPath [ "nextcloud" "location" ] "sda1" jsonData;
|
||||
};
|
||||
pleroma = {
|
||||
enable = lib.attrsets.attrByPath [ "pleroma" "enable" ] false jsonData;
|
||||
location = lib.attrsets.attrByPath [ "pleroma" "location" ] "sda1" jsonData;
|
||||
};
|
||||
jitsi = {
|
||||
enable = lib.attrsets.attrByPath [ "jitsi" "enable" ] false jsonData;
|
||||
};
|
||||
ocserv = {
|
||||
enable = lib.attrsets.attrByPath [ "ocserv" "enable" ] false jsonData;
|
||||
};
|
||||
ssh = {
|
||||
enable = lib.attrsets.attrByPath [ "ssh" "enable" ] true jsonData;
|
||||
rootKeys = lib.attrsets.attrByPath [ "ssh" "rootKeys" ] [ "" ] jsonData;
|
||||
passwordAuthentication = lib.attrsets.attrByPath [ "ssh" "passwordAuthentication" ] true jsonData;
|
||||
};
|
||||
email = {
|
||||
location = lib.attrsets.attrByPath [ "email" "location" ] "sda1" jsonData;
|
||||
};
|
||||
users = lib.attrsets.attrByPath [ "users" ] [ ] jsonData;
|
||||
volumes = lib.attrsets.attrByPath [ "volumes" ] [ ] jsonData;
|
||||
useBinds = lib.attrsets.attrByPath [ "useBinds" ] false jsonData;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ in
|
|||
services.jitsi-meet = {
|
||||
enable = config.services.userdata.jitsi.enable;
|
||||
hostName = "meet.${domain}";
|
||||
nginx.enable = false;
|
||||
nginx.enable = true;
|
||||
interfaceConfig = {
|
||||
SHOW_JITSI_WATERMARK = false;
|
||||
SHOW_WATERMARK_FOR_GUESTS = false;
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
{ pkgs, config, ... }:
|
||||
let
|
||||
cfg = config.services.userdata;
|
||||
in
|
||||
{
|
||||
fileSystems = { } // builtins.listToAttrs (builtins.map
|
||||
(volume: {
|
||||
name = "${volume.mountPoint}";
|
||||
value = {
|
||||
device = "${volume.device}";
|
||||
fsType = "${volume.fsType}";
|
||||
};
|
||||
})
|
||||
cfg.volumes);
|
||||
}
|
|
@ -10,6 +10,7 @@ in
|
|||
isNormalUser = false;
|
||||
isSystemUser = true;
|
||||
extraGroups = [ "ocserv" "acmerecievers" ];
|
||||
group = "ocserv";
|
||||
};
|
||||
services.ocserv = {
|
||||
enable = config.services.userdata.ocserv.enable;
|
||||
|
|
|
@ -1,32 +1,68 @@
|
|||
{ pkgs, config, ... }:
|
||||
{ pkgs, config, lib, ... }:
|
||||
let
|
||||
domain = config.services.userdata.domain;
|
||||
in
|
||||
{
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
enableReload = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
sslProtocols = lib.mkForce "TLSv1.2 TLSv1.3";
|
||||
sslCiphers = lib.mkForce "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:!SHA1:!SHA256:!SHA384:!DSS:!aNULL";
|
||||
clientMaxBodySize = "1024m";
|
||||
commonHttpConfig = ''
|
||||
map $scheme $hsts_header {
|
||||
https "max-age=31536000; includeSubdomains; preload";
|
||||
}
|
||||
'';
|
||||
|
||||
virtualHosts = {
|
||||
"${domain}" = {
|
||||
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
expires 10m;
|
||||
'';
|
||||
};
|
||||
"vpn.${domain}" = {
|
||||
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
expires 10m;
|
||||
'';
|
||||
};
|
||||
"git.${domain}" = {
|
||||
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
expires 10m;
|
||||
'';
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://127.0.0.1:3000";
|
||||
|
@ -37,51 +73,36 @@ in
|
|||
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
expires 10m;
|
||||
'';
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://127.0.0.1:80/";
|
||||
};
|
||||
};
|
||||
};
|
||||
"meet.${domain}" = {
|
||||
forceSSL = true;
|
||||
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
|
||||
root = pkgs.jitsi-meet;
|
||||
extraConfig = ''
|
||||
ssi on;
|
||||
'';
|
||||
locations = {
|
||||
"@root_path" = {
|
||||
extraConfig = ''
|
||||
rewrite ^/(.*)$ / break;
|
||||
'';
|
||||
};
|
||||
"~ ^/([^/\\?&:'\"]+)$" = {
|
||||
tryFiles = "$uri @root_path";
|
||||
};
|
||||
"=/http-bind" = {
|
||||
proxyPass = "http://localhost:5280/http-bind";
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
'';
|
||||
};
|
||||
"=/external_api.js" = {
|
||||
alias = "${pkgs.jitsi-meet}/libs/external_api.min.js";
|
||||
};
|
||||
"=/config.js" = {
|
||||
alias = "${pkgs.jitsi-meet}/config.js";
|
||||
};
|
||||
"=/interface_config.js" = {
|
||||
alias = "${pkgs.jitsi-meet}/interface_config.js";
|
||||
};
|
||||
};
|
||||
};
|
||||
"password.${domain}" = {
|
||||
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
expires 10m;
|
||||
'';
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://127.0.0.1:8222";
|
||||
|
@ -92,9 +113,20 @@ in
|
|||
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
expires 10m;
|
||||
'';
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://127.0.0.1:5050";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -103,14 +135,28 @@ in
|
|||
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
|
||||
root = "/var/www/social.${domain}";
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
expires 10m;
|
||||
'';
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://127.0.0.1:4000";
|
||||
};
|
||||
};
|
||||
extraConfig = ''
|
||||
client_max_body_size 1024m;
|
||||
'';
|
||||
};
|
||||
"meet.${domain}" = {
|
||||
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
|
||||
forceSSL = true;
|
||||
useACMEHost = domain;
|
||||
enableACME = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue