diff --git a/.travis.yml b/.travis.yml new file mode 100755 index 0000000..70f7a0d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: bash +sudo: false +script: + - bash -c 'shopt -s globstar; shellcheck -x **/*.sh' diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 index 383d618..9cecc1d --- a/LICENSE +++ b/LICENSE @@ -1,23 +1,674 @@ -This is free and unencumbered software released into the public domain. + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 -Anyone is free to copy, modify, publish, use, compile, sell, or distribute -this software, either in source code form or as a compiled binary, for any -purpose, commercial or non-commercial, and by any means. + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and -to the detriment of our heirs and + Preamble -successors. We intend this dedication to be an overt act of relinquishment -in perpetuity of all present and future rights to this software under copyright -law. + The GNU General Public License is a free, copyleft license for +software and other kinds of works. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH -THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + 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. -For more information, please refer to + 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 . + +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: + + {project} Copyright (C) {year} {fullname} + 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 +. + + 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 +. diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 883f9d9..99d920d --- a/README.md +++ b/README.md @@ -1,2 +1,90 @@ -# Nextcloud-Install +Nextcloud VM +============ +Server installation. Simplified. :cloud: +-------------------------------- + +#### Interactive Guidance +> **The Nextcloud VM** — _(aka **N**ext**c**loud **V**irtual **M**achine_ or _**NcVM**)_ — helps you create a personal or corporate [Nextcloud Server] _faster_ and _easier._ Fundamentally, NcVM is a carefully crafted _family_ of [\*nix] scripts which interactively guide you through a quality-controlled installation to obtain an [A+ security-rated] Nextcloud instance. + +#### Curated Extras +> The Nextcloud [app store] extends core features by allowing you to enable a multitude of free one-click apps. However, _integration apps_ there like [Collabora Online] and [ONLYOFFICE] are solely _bridges_ to Nextcloud. You’re still required to install those services _separately_, which can be complex. NcVM provides optional _**full installation of select curated apps**_, including those and others. Monitor and manage your cloud using any web browser with NcVM’s hand-picked collection of power utilities featuring stunning, modern UIs. + +#### All Systems Go +> NcVM can check for and install _stable_ updates to keep things current, smooth, and secure. + +-------------------- + +## Support the development +* [Create a PR](https://help.github.com/articles/creating-a-pull-request/) and improve the code +* Report [your issue](https://github.com/nextcloud/vm/issues/new) +* Help us with [existing issues](https://github.com/nextcloud/vm/issues) +* Write scripts so that the release process becomes automated with [Vagrant](https://www.vagrantup.com/docs/getting-started/), [Terraform](https://www.terraform.io/) or similar +* **[Donate](https://shop.hanssonit.se/product-category/donate/) or buy our [pre-configured VMs](https://shop.hanssonit.se/product-category/virtual-machine/): 500 GB, 1 TB, 2TB or Hyper-V.** + +## Full documentation +* [VM](https://docs.hanssonit.se/s/W6fMouPiqQz3_Mog/virtual-machines-vm/d/W6fMquPiqQz3_Moi/nextcloud-vm) (the easiest option) +* [Install with scripts](https://docs.hanssonit.se/s/bj0vl1ihv0jgrmfm08j0/build-your-own/d/bj0vl4ahv0jgrmfm0950/nextcloud-vm) (if you feel brave) +* [FAQ](https://docs.hanssonit.se/s/bj101nihv0jgrmfm09f0/faq/d/bj101pihv0jgrmfm0a10/nextcloud-vm?currentPageId=bj101sqhv0jgrmfm0a1g) (Frequently Asked Questions) +* [Machine configuration](https://docs.hanssonit.se/s/W6fMouPiqQz3_Mog/virtual-machines-vm/d/W7Du9uPiqQz3_Mr1/machine-setup-nextcloud-vm) (of the released version) + +## I want to test a Release Candidate (RC), or Beta! +No problem, brave explorer! We made it simple. + +In some cases we do pre-releases of the VM as well. Those can be found in the [TESTING](https://cloud.hanssonit.se/s/zjsqkrSpzqJGE9N?path=%2FTESTING) folder on the download server. If you want to try the latest version yourself, just follow the steps below: +1. Download the latest [nextcloud_update.sh](https://raw.githubusercontent.com/nextcloud/vm/master/nextcloud_update.sh) to your server. +2. Put the below variables right above line 256 **(# Major versions unsupported)** +3. Run nextcloud_update.sh + +To test a specific RC version: + +``` +NCREPO="https://download.nextcloud.com/server/prereleases" +NCVERSION=16.0.0RC1 +STABLEVERSION="nextcloud-$NCVERSION" +``` + +Or the latest Beta: +``` +NCREPO="https://download.nextcloud.com/server/prereleases" +NCVERSION=$(curl -s -m 900 $NCREPO/ | sed --silent 's/.*href="nextcloud-\([^"]\+\).zip.asc".*/\1/p' | sort --version-sort | tail -1) +STABLEVERSION="nextcloud-$NCVERSION" +``` + +## First look +![alt tag](https://github.com/nextcloud/nextcloud.com/blob/master/assets/img/features/VMwelcome.png) + +## The usual tags +**Downloads from Github (not the main downloads location):** +
+![Downloads](https://img.shields.io/github/downloads/nextcloud/vm/total.svg) +
+**Downloads from main server:** +
+~100 per day since 2016 +
+**Build Status:** +
+[![Build Status](https://travis-ci.org/nextcloud/vm.svg?branch=master)](https://travis-ci.org/nextcloud/vm) +
+**Stability Status:** +
+![Stability Status](https://img.shields.io/badge/stability-stable-brightgreen.svg) + +## Current [maintainers](https://github.com/nextcloud/vm/graphs/contributors) +* [Daniel Hanson](https://github.com/enoch85) @ [T&M Hansson IT AB](https://www.hanssonit.se) +* You? :) + +## Special thanks to +* [Ezra Holm](https://github.com/ezraholm50) @ [Tech and Me](https://www.techandme.se) +* [Luis Guzman](https://github.com/Ark74) @ [SwITNet](https://switnet.net) +* [Stefan Heitmüller](https://github.com/morph027) @ [morph027's Blog](https://morph027.gitlab.io/) +* [Lorenzo Faleschini](https://github.com/penzoiders) +* [Georg Großmann](https://github.com/ggeorgg) + +[Nextcloud Server]: https://bit.ly/2CHIUkA +[app store]: https://bit.ly/2HUy4v9 +[\*nix]: https://bit.ly/2UaCC7b +[A+ security-rated]: https://bit.ly/2mvlyJ3 +[Collabora Online]: https://bit.ly/2WjVVZ8 +[ONLYOFFICE]: https://bit.ly/2FA0TKj diff --git a/apps/adminer.sh b/apps/adminer.sh new file mode 100755 index 0000000..19432b5 --- /dev/null +++ b/apps/adminer.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +print_text_in_color "$ICyan" "Installing and securing Adminer..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +# Warn user about HTTP/2 +http2_warn Adminer + +# Check that the script can see the external IP (apache fails otherwise) +if [ -z "$WANIP4" ] +then + print_text_in_color "$IRed" "WANIP4 is an emtpy value, Apache will fail on reboot due to this. Please check your network and try again." + sleep 3 + exit 1 +fi + +# Check distrobution and version +check_distro_version + +# Install Adminer +apt update -q4 & spinner_loading +install_if_not adminer +curl_to_dir "http://www.adminer.org" "latest.php" "$ADMINERDIR" +ln -s "$ADMINERDIR"/latest.php "$ADMINERDIR"/adminer.php + +cat << ADMINER_CREATE > "$ADMINER_CONF" +Alias /adminer.php $ADMINERDIR/adminer.php + + + + +DirectoryIndex adminer.php + +AllowOverride None + +# Only allow connections from localhost: +Require ip $GATEWAY/24 + + +ADMINER_CREATE + +# Enable config +check_command a2enconf adminer.conf + +if ! restart_webserver +then +msg_box "Apache2 could not restart... +The script will exit." + exit 1 +else +msg_box "Adminer was sucessfully installed and can be reached here: +http://$ADDRESS/adminer.php + +You can download more plugins and get more information here: +https://www.adminer.org + +Your PostgreSQL connection information can be found in $NCPATH/config/config.php + +In case you try to access Adminer and get 'Forbidden' you need to change the IP in: +$ADMINER_CONF" +fi + +exit diff --git a/apps/collabora.sh b/apps/collabora.sh new file mode 100755 index 0000000..7c0155b --- /dev/null +++ b/apps/collabora.sh @@ -0,0 +1,208 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +NC_UPDATE=1 && COLLABORA_INSTALL=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset NC_UPDATE +unset COLLABORA_INSTALL + +print_text_in_color "$ICyan" "Installing Collabora..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +# Nextcloud 13 is required. +lowest_compatible_nc 13 + +# Test RAM size (2GB min) + CPUs (min 2) +ram_check 2 Collabora +cpu_check 2 Collabora + +# Notification +msg_box "Before you start, please make sure that port 80+443 is directly forwarded to this machine!" + +# Get the latest packages +apt update -q4 & spinner_loading + +# Check if Nextcloud is installed +print_text_in_color "$ICyan" "Checking if Nextcloud is installed..." +if ! curl -s https://"${NCDOMAIN//\\/}"/status.php | grep -q 'installed":true' +then +msg_box "It seems like Nextcloud is not installed or that you don't use https on: +${NCDOMAIN//\\/}. +Please install Nextcloud and make sure your domain is reachable, or activate SSL +on your domain to be able to run this script. + +If you use the Nextcloud VM you can use the Let's Encrypt script to get SSL and activate your Nextcloud domain. +When SSL is activated, run these commands from your terminal: +sudo curl -sLO $APP/collabora.sh +sudo bash collabora.sh" + exit 1 +fi + +# Check if $SUBDOMAIN exists and is reachable +print_text_in_color "$ICyan" "Checking if $SUBDOMAIN exists and is reachable..." +domain_check_200 "$SUBDOMAIN" + +# Check open ports with NMAP +check_open_port 80 "$SUBDOMAIN" +check_open_port 443 "$SUBDOMAIN" + +# Install Docker +install_docker + +# Check if OnlyOffice or Collabora is previously installed +# If yes, then stop and prune the docker container +docker_prune_this 'collabora/code' +docker_prune_this 'onlyoffice/documentserver' + +# Disable RichDocuments (Collabora App) if activated +if [ -d "$NC_APPS_PATH"/richdocuments ] +then + occ_command app:remove richdocuments +fi + +# Disable OnlyOffice (Collabora App) if activated +if [ -d "$NC_APPS_PATH"/onlyoffice ] +then + occ_command app:remove onlyoffice +fi + +# Install Collabora docker +docker pull collabora/code:latest +docker run -t -d -p 127.0.0.1:9980:9980 -e "domain=$NCDOMAIN" --restart always --name code --cap-add MKNOD collabora/code + +# Install Apache2 +install_if_not apache2 + +# Enable Apache2 module's +a2enmod proxy +a2enmod proxy_wstunnel +a2enmod proxy_http +a2enmod ssl + +if [ -f "$HTTPS_CONF" ] +then + a2dissite "$SUBDOMAIN.conf" + rm -f "$HTTPS_CONF" +fi + +# Create Vhost for Collabora online in Apache2 +if [ ! -f "$HTTPS_CONF" ]; +then + cat << HTTPS_CREATE > "$HTTPS_CONF" + + ServerName $SUBDOMAIN:443 + + + Options -Indexes + + + # SSL configuration, you may want to take the easy route instead and use Lets Encrypt! + SSLEngine on + SSLCertificateChainFile $CERTFILES/$SUBDOMAIN/chain.pem + SSLCertificateFile $CERTFILES/$SUBDOMAIN/cert.pem + SSLCertificateKeyFile $CERTFILES/$SUBDOMAIN/privkey.pem + SSLOpenSSLConfCmd DHParameters $DHPARAMS + SSLProtocol all -SSLv2 -SSLv3 + SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS + SSLHonorCipherOrder on + SSLCompression off + + # Encoded slashes need to be allowed + AllowEncodedSlashes NoDecode + + # Container uses a unique non-signed certificate + SSLProxyEngine On + SSLProxyVerify None + SSLProxyCheckPeerCN Off + SSLProxyCheckPeerName Off + + # keep the host + ProxyPreserveHost On + + # static html, js, images, etc. served from loolwsd + # loleaflet is the client part of LibreOffice Online + ProxyPass /loleaflet https://127.0.0.1:9980/loleaflet retry=0 + ProxyPassReverse /loleaflet https://127.0.0.1:9980/loleaflet + + # WOPI discovery URL + ProxyPass /hosting/discovery https://127.0.0.1:9980/hosting/discovery retry=0 + ProxyPassReverse /hosting/discovery https://127.0.0.1:9980/hosting/discovery + + # Main websocket + ProxyPassMatch "/lool/(.*)/ws$" wss://127.0.0.1:9980/lool/\$1/ws nocanon + + # Admin Console websocket + ProxyPass /lool/adminws wss://127.0.0.1:9980/lool/adminws + + # Download as, Fullscreen presentation and Image upload operations + ProxyPass /lool https://127.0.0.1:9980/lool + ProxyPassReverse /lool https://127.0.0.1:9980/lool + +HTTPS_CREATE + + if [ -f "$HTTPS_CONF" ]; + then + print_text_in_color "$IGreen" "$HTTPS_CONF was successfully created." + sleep 1 + else + print_text_in_color "$IRed" "Unable to create vhost, exiting..." + print_text_in_color "$IRed" "Please report this issue here $ISSUES" + exit 1 + fi +fi + +# Install certbot (Let's Encrypt) +install_certbot + +# Generate certs +if le_subdomain +then + # Generate DHparams chifer + if [ ! -f "$DHPARAMS" ] + then + openssl dhparam -dsaparam -out "$DHPARAMS" 4096 + fi + printf "%b" "${IGreen}Certs are generated!\n${Color_Off}" + a2ensite "$SUBDOMAIN.conf" + restart_webserver + # Install Collabora App + occ_command app:install richdocuments +else + print_text_in_color "$IRed" "It seems like no certs were generated, please report this issue here: $ISSUES" + any_key "Press any key to continue... " + restart_webserver +fi + +# Set config for RichDocuments (Collabora App) +if [ -d "$NC_APPS_PATH"/richdocuments ] +then + occ_command config:app:set richdocuments wopi_url --value=https://"$SUBDOMAIN" + chown -R www-data:www-data "$NC_APPS_PATH" + occ_command config:system:set trusted_domains 3 --value="$SUBDOMAIN" + # Add prune command + { + echo "#!/bin/bash" + echo "docker system prune -a --force" + echo "exit" + } > "$SCRIPTS/dockerprune.sh" + chmod a+x "$SCRIPTS/dockerprune.sh" + crontab -u root -l | { cat; echo "@weekly $SCRIPTS/dockerprune.sh"; } | crontab -u root - + print_text_in_color "$ICyan" "Docker automatic prune job added." + service docker restart + docker restart code + print_text_in_color "$IGreen" "Collabora is now successfully installed." + any_key "Press any key to continue... " +fi + +exit diff --git a/apps/fail2ban.sh b/apps/fail2ban.sh new file mode 100755 index 0000000..31df5a7 --- /dev/null +++ b/apps/fail2ban.sh @@ -0,0 +1,132 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ +# Inspired by https://github.com/nextcloud/nextcloudpi/blob/master/etc/nextcloudpi-config.d/fail2ban.sh + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +NC_UPDATE=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset NC_UPDATE + +print_text_in_color "$ICyan" "Installing Fail2ban..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +# Nextcloud 13 is required. +lowest_compatible_nc 13 + +### Local variables ### +# location of Nextcloud logs +NCLOG="$(find / -name nextcloud.log)" +# time to ban an IP that exceeded attempts +BANTIME_=600000 +# cooldown time for incorrect passwords +FINDTIME_=1800 +# failed attempts before banning an IP +MAXRETRY_=20 + +apt update -q4 & spinner_loading +check_command apt install fail2ban -y +check_command update-rc.d fail2ban disable + +if [ -z "$NCLOG" ] +then + print_text_in_color "$IRed" "nextcloud.log not found" + print_text_in_color "$IRed" "Please add your logpath to $NCPATH/config/config.php and restart this script." + exit 1 +else + chown www-data:www-data "$NCLOG" +fi + +# Set values in config.php +occ_command config:system:set loglevel --value=2 +occ_command config:system:set log_type --value=file +occ_command config:system:set logfile --value="$NCLOG" +occ_command config:system:set logtimezone --value="$(cat /etc/timezone)" + +# Create nextcloud.conf file +cat << NCONF > /etc/fail2ban/filter.d/nextcloud.conf +[Definition] +failregex=^{"reqId":".*","remoteAddr":".*","app":"core","message":"Login failed: '.*' \(Remote IP: ''\)","level":2,"time":".*"}$ + ^{"reqId":".*","level":2,"time":".*","remoteAddr":".*","app":"core".*","message":"Login failed: '.*' \(Remote IP: ''\)".*}$ + ^.*\"remoteAddr\":\"\".*Trusted domain error.*\$ +NCONF + +# Disable default Debian sshd chain +check_command sed -i "s|true|false|g" /etc/fail2ban/jail.d/defaults-debian.conf + +# Create jail.local file +cat << FCONF > /etc/fail2ban/jail.local +# The DEFAULT allows a global definition of the options. They can be overridden +# in each jail afterwards. +[DEFAULT] + +# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not +# ban a host which matches an address in this list. Several addresses can be +# defined using space separator. +ignoreip = 127.0.0.1/8 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 + +# "bantime" is the number of seconds that a host is banned. +bantime = $BANTIME_ + +# A host is banned if it has generated "maxretry" during the last "findtime" +# seconds. +findtime = $FINDTIME_ +maxretry = $MAXRETRY_ + +# +# ACTIONS +# +banaction = iptables-multiport +protocol = tcp +chain = INPUT +action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] +action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] +action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] +action = %(action_)s + +# +# SSH +# + +[ssh] + +enabled = true +port = ssh +filter = sshd +logpath = /var/log/auth.log +maxretry = $MAXRETRY_ + +# +# HTTP servers +# + +[nextcloud] + +enabled = true +port = http,https +filter = nextcloud +logpath = $NCLOG +maxretry = $MAXRETRY_ +FCONF + +# Update settings +check_command update-rc.d fail2ban defaults +check_command update-rc.d fail2ban enable +check_command service fail2ban restart + +# The End +msg_box "Fail2ban is now sucessfully installed. + +Please use 'fail2ban-client set nextcloud unbanip ' to unban certain IPs +You can also use 'iptables -L -n' to check which IPs that are banned" + +exit diff --git a/apps/fulltextsearch.sh b/apps/fulltextsearch.sh new file mode 100755 index 0000000..c27ebc1 --- /dev/null +++ b/apps/fulltextsearch.sh @@ -0,0 +1,133 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ +# SwITNet Ltd © - 2019, https://switnet.net/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +NC_UPDATE=1 && ES_INSTALL=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset NC_UPDATE +unset ES_INSTALL + +print_text_in_color "$ICyan" "Installing Elastic Search & Full Text Search on Nextcloud..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Must be root +root_check + +# Nextcloud 13 is required. +lowest_compatible_nc 13 + +# Make sure there is an Nextcloud installation +if ! [ "$(occ_command -V)" ] +then + msg_box "It seems there is no Nextcloud server installed, please check your installation." + exit 1 +fi + +# Disable and remove Nextant + Solr +if [ -d "$NC_APPS_PATH"/nextant ] +then + # Remove Nextant + msg_box "We will now remove Nextant + Solr and replace it with Full Text Search" + occ_command app:disable nextant + rm -rf $NC_APPS_PATH/nextant + + # Remove Solr + service solr stop + rm -rf /var/solr + rm -rf /opt/solr* + rm /etc/init.d/solr + deluser --remove-home solr + deluser --group solr +fi + +# Reset Full Text Search to be able to index again, and also remove the app to be able to install it again +if [ -d $NC_APPS_PATH/fulltextsearch ] +then + print_text_in_color "$ICyan" "Removing old version of Full Text Search and resetting the app..." + sudo -u www-data php $NCPATH/occ fulltextsearch:reset + occ_command app:disable fulltextsearch + rm -rf $NC_APPS_PATH/fulltextsearch +fi +if [ -d $NC_APPS_PATH/fulltextsearch_elasticsearch ] +then + occ_command app:disable fulltextsearch_elasticsearch + rm -rf $NC_APPS_PATH/fulltextsearch_elasticsearch +fi +if [ -d $NC_APPS_PATH/files_fulltextsearch ] +then + occ_command app:disable files_fulltextsearch + rm -rf $NC_APPS_PATH/files_fulltextsearch +fi + +# Check & install docker +install_docker +set_max_count +mkdir -p "$RORDIR" +if does_this_docker_exist "$nc_fts" +then + docker_prune_this "$nc_fts" +else + docker pull "$nc_fts" +fi + +# Create configuration YML +cat << YML_CREATE > /opt/es/readonlyrest.yml +readonlyrest: + access_control_rules: + - name: Accept requests from cloud1 on $INDEX_USER-index + groups: ["cloud1"] + indices: ["$INDEX_USER-index"] + + users: + - username: $INDEX_USER + auth_key: $INDEX_USER:$ROREST + groups: ["cloud1"] +YML_CREATE + +# Set persmissions +chown 1000:1000 -R $RORDIR +chmod ug+rwx -R $RORDIR + +# Run Elastic Search Docker +docker run -d --restart always \ +--name $fts_es_name \ +--ulimit memlock=-1:-1 \ +--ulimit nofile=65536:65536 \ +-p 9200:9200 \ +-p 9300:9300 \ +-v esdata:/usr/share/elasticsearch/data \ +-v /opt/es/readonlyrest.yml:/usr/share/elasticsearch/config/readonlyrest.yml \ +-e "discovery.type=single-node" \ +-e "bootstrap.memory_lock=true" \ +-e ES_JAVA_OPTS="-Xms512M -Xmx512M" \ +-i -t $nc_fts + +# Wait for bootstraping +docker restart $fts_es_name +countdown "Waiting for docker bootstraping..." "20" +docker logs $fts_es_name + +# Get Full Text Search app for nextcloud +install_and_enable_app fulltextsearch +install_and_enable_app fulltextsearch_elasticsearch +install_and_enable_app files_fulltextsearch +chown -R www-data:www-data $NC_APPS_PATH + +# Final setup +occ_command fulltextsearch:configure '{"search_platform":"OCA\\FullTextSearch_ElasticSearch\\Platform\\ElasticSearchPlatform"}' +occ_command fulltextsearch_elasticsearch:configure "{\"elastic_host\":\"http://${INDEX_USER}:${ROREST}@localhost:9200\",\"elastic_index\":\"${INDEX_USER}-index\"}" +occ_command files_fulltextsearch:configure "{\"files_pdf\":\"1\",\"files_office\":\"1\"}" +if occ_command fulltextsearch:index < /dev/null +then +msg_box "Full Text Search was successfully installed!" +fi + +exit diff --git a/apps/netdata.sh b/apps/netdata.sh new file mode 100755 index 0000000..bb1c4e5 --- /dev/null +++ b/apps/netdata.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +print_text_in_color "$ICyan" "Installing Netdata..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Download and install Netdata +if [ -d /etc/netdata ] +then +msg_box "Netdata seems to be installed. +We will now remove Netdata and reinstall the latest stable version" + # Uninstall + if [ -f /usr/src/netdata.git/netdata-uninstaller.sh ] + then + if ! yes | bash /usr/src/netdata.git/netdata-uninstaller.sh --force + then + rm -Rf /usr/src/netdata.git + fi + elif [ -f /usr/libexec/netdata-uninstaller.sh ] + then + yes | bash /usr/libexec/netdata-uninstaller.sh --yes + fi + userdel netdata + groupdel netdata + gpasswd -d netdata adm + gpasswd -d netdata proxy + # Install + is_process_running dpkg + is_process_running apt + apt update -q4 & spinner_loading + curl_to_dir https://my-netdata.io kickstart.sh $SCRIPTS + sudo -u "$UNIXUSER" bash $SCRIPTS/kickstart.sh all --dont-wait --no-updates --stable-channel + rm -f $SCRIPTS/kickstart.sh +else + # Install + is_process_running dpkg + is_process_running apt + apt update -q4 & spinner_loading + curl_to_dir https://my-netdata.io kickstart.sh $SCRIPTS + sudo -u "$UNIXUSER" bash $SCRIPTS/kickstart.sh all --dont-wait --no-updates --stable-channel + rm -f $SCRIPTS/kickstart.sh +fi + +# Check Netdata instructions after script is done +any_key "Please check information above and press any key to continue..." + +# Installation done? +if [ -d /etc/netdata ] +then +msg_box "Netdata is now installed and can be accessed from this address: + +http://$ADDRESS:19999 + +If you want to reach it from the internet you need to open port 19999 in your firewall. +If you don't know how to open ports, please follow this guide: +https://www.techandme.se/open-port-80-443/ + +After you have opened the correct port, then you can visit Netdata from your domain: + +http://$(hostname -f):19999 and or http://yourdomanin.com:19999 + +You can find more configuration options in their WIKI: +https://docs.netdata.cloud/daemon/config#configuration-guide" + +# Cleanup +rm -rf /tmp/netdata* +fi + +exit diff --git a/apps/onlyoffice.sh b/apps/onlyoffice.sh new file mode 100755 index 0000000..2d19a0f --- /dev/null +++ b/apps/onlyoffice.sh @@ -0,0 +1,197 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +NC_UPDATE=1 && OO_INSTALL=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset NC_UPDATE +unset OO_INSTALL + +print_text_in_color "$ICyan" "Installing OnlyOffice..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +# Nextcloud 13 is required. +lowest_compatible_nc 13 + +# Test RAM size (2GB min) + CPUs (min 2) +ram_check 2 OnlyOffice +cpu_check 2 OnlyOffice + +# Notification +msg_box "Before you start, please make sure that port 80+443 is directly forwarded to this machine!" + +# Get the latest packages +apt update -q4 & spinner_loading + +# Check if Nextcloud is installed +print_text_in_color "$ICyan" "Checking if Nextcloud is installed..." +if ! curl -s https://"${NCDOMAIN//\\/}"/status.php | grep -q 'installed":true' +then +msg_box "It seems like Nextcloud is not installed or that you don't use https on: +${NCDOMAIN//\\/}. +Please install Nextcloud and make sure your domain is reachable, or activate SSL +on your domain to be able to run this script. +If you use the Nextcloud VM you can use the Let's Encrypt script to get SSL and activate your Nextcloud domain. +When SSL is activated, run these commands from your terminal: +sudo curl -sLO $APP/onlyoffice.sh +sudo bash onlyoffice.sh" + exit 1 +fi + +# Check if $SUBDOMAIN exists and is reachable +print_text_in_color "$ICyan" "Checking if $SUBDOMAIN exists and is reachable..." +domain_check_200 "$SUBDOMAIN" + +# Check open ports with NMAP +check_open_port 80 "$SUBDOMAIN" +check_open_port 443 "$SUBDOMAIN" + +# Install Docker +install_docker + +# Check if OnlyOffice or Collabora is previously installed +# If yes, then stop and prune the docker container +docker_prune_this 'onlyoffice/documentserver' +docker_prune_this 'collabora/code' + +# Disable RichDocuments (Collabora App) if activated +if [ -d "$NC_APPS_PATH"/richdocuments ] +then + occ_command app:remove richdocuments +fi + +# Disable OnlyOffice (Collabora App) if activated +if [ -d "$NC_APPS_PATH"/onlyoffice ] +then + occ_command app:remove onlyoffice +fi + +# Install Onlyoffice docker +docker pull onlyoffice/documentserver:latest +docker run -i -t -d -p 127.0.0.3:9090:80 --restart always --name onlyoffice onlyoffice/documentserver + +# Install apache2 +install_if_not apache2 + +# Enable Apache2 module's +a2enmod proxy +a2enmod proxy_wstunnel +a2enmod proxy_http +a2enmod ssl + +if [ -f "$HTTPS_CONF" ] +then + a2dissite "$SUBDOMAIN.conf" + rm -f "$HTTPS_CONF" +fi + +# Create Vhost for OnlyOffice online in Apache2 +if [ ! -f "$HTTPS_CONF" ]; +then + cat << HTTPS_CREATE > "$HTTPS_CONF" + + ServerName $SUBDOMAIN:443 + + SSLEngine on + ServerSignature On + SSLHonorCipherOrder on + + SSLCertificateChainFile $CERTFILES/$SUBDOMAIN/chain.pem + SSLCertificateFile $CERTFILES/$SUBDOMAIN/cert.pem + SSLCertificateKeyFile $CERTFILES/$SUBDOMAIN/privkey.pem + SSLOpenSSLConfCmd DHParameters $DHPARAMS + + SSLProtocol all -SSLv2 -SSLv3 + SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS + + LogLevel warn + CustomLog ${APACHE_LOG_DIR}/access.log combined + ErrorLog ${APACHE_LOG_DIR}/error.log + + # Just in case - see below + SSLProxyEngine On + SSLProxyVerify None + SSLProxyCheckPeerCN Off + SSLProxyCheckPeerName Off + + # contra mixed content warnings + RequestHeader set X-Forwarded-Proto "https" + + # basic proxy settings + ProxyRequests off + + ProxyPassMatch (.*)(\/websocket)$ "ws://127.0.0.3:9090/$1$2" + ProxyPass / "http://127.0.0.3:9090/" + ProxyPassReverse / "http://127.0.0.3:9090/" + + + ProxyPassReverse / + + +HTTPS_CREATE + + if [ -f "$HTTPS_CONF" ]; + then + print_text_in_color "$IGreen" "$HTTPS_CONF was successfully created." + sleep 1 + else + print_text_in_color "$IRed" "Unable to create vhost, exiting..." + print_text_in_color "$IRed" "Please report this issue here $ISSUES" + exit 1 + fi +fi + +# Install certbot (Let's Encrypt) +install_certbot + +# Generate certs +if le_subdomain +then + # Generate DHparams chifer + if [ ! -f "$DHPARAMS" ] + then + openssl dhparam -dsaparam -out "$DHPARAMS" 4096 + fi + printf "%b" "${IGreen}Certs are generated!\n${Color_Off}" + a2ensite "$SUBDOMAIN.conf" + restart_webserver + # Install OnlyOffice + occ_command app:install onlyoffice +else + print_text_in_color "$IRed" "It seems like no certs were generated, please report this issue here: $ISSUES" + any_key "Press any key to continue... " + restart_webserver +fi + +# Set config for OnlyOffice +if [ -d "$NC_APPS_PATH"/onlyoffice ] +then + occ_command config:app:set onlyoffice DocumentServerUrl --value=https://"$SUBDOMAIN/" + chown -R www-data:www-data "$NC_APPS_PATH" + occ_command config:system:set trusted_domains 3 --value="$SUBDOMAIN" +# Add prune command + { + echo "#!/bin/bash" + echo "docker system prune -a --force" + echo "exit" + } > "$SCRIPTS/dockerprune.sh" + chmod a+x "$SCRIPTS/dockerprune.sh" + crontab -u root -l | { cat; echo "@weekly $SCRIPTS/dockerprune.sh"; } | crontab -u root - + print_text_in_color "$ICyan" "Docker automatic prune job added." + service docker restart + docker restart onlyoffice + print_text_in_color "$IGreen" "OnlyOffice is now successfully installed." + any_key "Press any key to continue... " +fi + +exit diff --git a/apps/previewgenerator.sh b/apps/previewgenerator.sh new file mode 100755 index 0000000..83a5b0f --- /dev/null +++ b/apps/previewgenerator.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +msg_box "Please note that this will put your server at risk as it will install a package called 'imagick' which is known to have several flaws. + +You can check this issue to understand why: https://github.com/nextcloud/vm/issues/743 + +You can choose to cancel installing this in the next step." +if [[ "no" == $(ask_yes_or_no "Do you still want to continue?") ]] +then + exit +else + sleep 1 +fi + +# Install preview generator +install_and_enable_app previewgenerator + +# Run the first preview generation and add crontab +if [ -d "$NC_APPS_PATH/previewgenerator" ] +then + # Enable previews (remove the # to enable the specific preview) + occ_command config:system:set enable_previews --value=true --type=boolean + occ_command config:system:set preview_libreoffice_path --value="/usr/bin/libreoffice" +# occ_command config:system:set enabledPreviewProviders 0 --value="OC\\Preview\\PNG" +# occ_command config:system:set enabledPreviewProviders 1 --value="OC\\Preview\\JPEG" +# occ_command config:system:set enabledPreviewProviders 2 --value="OC\\Preview\\GIF" +# occ_command config:system:set enabledPreviewProviders 3 --value="OC\\Preview\\BMP" +# occ_command config:system:set enabledPreviewProviders 4 --value="OC\\Preview\\XBitmap" +# occ_command config:system:set enabledPreviewProviders 5 --value="OC\\Preview\\MarkDown" +# occ_command config:system:set enabledPreviewProviders 6 --value="OC\\Preview\\MP3" +# occ_command config:system:set enabledPreviewProviders 7 --value="OC\\Preview\\TXT" +# occ_command config:system:set enabledPreviewProviders 8 --value="OC\\Preview\\Illustrator" +# occ_command config:system:set enabledPreviewProviders 9 --value="OC\\Preview\\Movie" +# occ_command config:system:set enabledPreviewProviders 10 --value="OC\\Preview\\MSOffice2003" +# occ_command config:system:set enabledPreviewProviders 11 --value="OC\\Preview\\MSOffice2007" +# occ_command config:system:set enabledPreviewProviders 12 --value="OC\\Preview\\MSOfficeDoc" +# occ_command config:system:set enabledPreviewProviders 13 --value="OC\\Preview\\OpenDocument" +# occ_command config:system:set enabledPreviewProviders 14 --value="OC\\Preview\\PDF" +# occ_command config:system:set enabledPreviewProviders 15 --value="OC\\Preview\\Photoshop" +# occ_command config:system:set enabledPreviewProviders 16 --value="OC\\Preview\\Postscript" +# occ_command config:system:set enabledPreviewProviders 17 --value="OC\\Preview\\StarOffice" +# occ_command config:system:set enabledPreviewProviders 18 --value="OC\\Preview\\SVG" +# occ_command config:system:set enabledPreviewProviders 19 --value="OC\\Preview\\TIFF" +# occ_command config:system:set enabledPreviewProviders 20 --value="OC\\Preview\\Font" + + # Set aspect ratio + occ_command config:app:set --value="32 64 1024" previewgenerator squareSizes + occ_command config:app:set --value="64 128 1024" previewgenerator widthSizes + occ_command config:app:set --value="64 256 1024" previewgenerator heightSizes + + # Add crotab + crontab -u www-data -l | { cat; echo "@daily php -f $NCPATH/occ preview:pre-generate >> /var/log/previewgenerator.log"; } | crontab -u www-data - + touch /var/log/previewgenerator.log + chown www-data:www-data /var/log/previewgenerator.log + + # Install needed dependencies + install_if_not ffmpeg + install_if_not libreoffice + install_if_not php-imagick + install_if_not libmagickcore-6.q16-3-extra + + # Pre generate everything + occ_command preview:generate-all +fi + +exit diff --git a/apps/spreedme.sh b/apps/spreedme.sh new file mode 100755 index 0000000..863def3 --- /dev/null +++ b/apps/spreedme.sh @@ -0,0 +1,128 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +NC_UPDATE=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset NC_UPDATE + +print_text_in_color "$ICyan" "Installing Spreed.ME..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +if ! is_root +then + printf "\n${Red}Sorry, you are not root.\n${Color_Off}You must type: ${ICyan}sudo ${Color_Off}bash %s/nextcloud_install_production.sh\n" "$SCRIPTS" + exit 1 +fi + +# Check if Nextcloud exists +root_check + +# Nextcloud 13 is required. +lowest_compatible_nc 13 + +# Install if missing +install_if_not apache2 +install_if_not snapd + +# Install Nextcloud Spreed.ME Snap +if [ -d "$SNAPDIR" ] +then + print_text_in_color "$ICyan" "Spreed.ME Snap already seems to be installed and will now be re-installed..." + snap remove spreedme + rm -rf "$SNAPDIR" + snap install --edge spreedme +else + snap install --edge spreedme +fi + +# Install and activate the Spreed.ME app +if [ -d "$NC_APPS_PATH/spreedme" ] +then + # Remove + occ_command app:disable spreedme + print_text_in_color "$ICyan" "Spreed.ME app already seems to be installed and will now be re-installed..." + rm -R "$NC_APPS_PATH/spreedme" + # Reinstall + occ_command app:install spreedme +else + occ_command app:install spreedme +fi +occ_command app:enable spreedme +chown -R www-data:www-data "$NC_APPS_PATH" + +# Generate secret keys +SHAREDSECRET=$(openssl rand -hex 32) +TEMPLINK=$(openssl rand -hex 32) +sed -i "s|sharedsecret_secret = .*|sharedsecret_secret = $SHAREDSECRET|g" "$SNAPDIR/current/server.conf" + +# Populate the else empty config file (uses database for content by default) +cp "$NCPATH/apps/spreedme/config/config.php.in" "$NCPATH/apps/spreedme/config/config.php" + +# Place the key in the NC app config +sed -i "s|.*SPREED_WEBRTC_SHAREDSECRET.*| const SPREED_WEBRTC_SHAREDSECRET = '$SHAREDSECRET';|g" "$NCPATH/apps/spreedme/config/config.php" + +# Allow to create temporary links +sed -i "s|const OWNCLOUD_TEMPORARY_PASSWORD_LOGIN_ENABLED.*|const OWNCLOUD_TEMPORARY_PASSWORD_LOGIN_ENABLED = true;|g" "$NCPATH/apps/spreedme/config/config.php" + +# Set temporary links hash +sed -i "s|const OWNCLOUD_TEMPORARY_PASSWORD_SIGNING_KEY.*|const OWNCLOUD_TEMPORARY_PASSWORD_SIGNING_KEY = '$TEMPLINK';|g" "$NCPATH/apps/spreedme/config/config.php" + + +# Enable Apache mods +a2enmod proxy \ + proxy_wstunnel \ + proxy_http \ + headers + +# Add config to vhost +VHOST=/etc/apache2/spreedme.conf +if [ ! -f $VHOST ] +then +cat << VHOST > "$VHOST" + + ProxyPass http://127.0.0.1:8080/webrtc + ProxyPassReverse /webrtc + + + + ProxyPass ws://127.0.0.1:8080/webrtc/ws + + + ProxyVia On + ProxyPreserveHost On + RequestHeader set X-Forwarded-Proto 'https' env=HTTPS + # RequestHeader set X-Forwarded-Proto 'https' # Use this if you are behind a (Nginx) reverse proxy with http backends +VHOST +fi + +if ! grep -Fxq "Include $VHOST" /etc/apache2/apache2.conf +then + sed -i "145i Include $VHOST" "/etc/apache2/apache2.conf" +fi + +# Restart services +restart_webserver +if ! systemctl restart snap.spreedme.spreed-webrtc.service +then +msg_box "Something is wrong, the installation did not finish correctly. + +Please report this to $ISSUES" + exit 1 +else +msg_box "Success! Spreed.ME is now installed and configured. + +You may have to change SPREED_WEBRTC_ORIGIN in: +(sudo nano) $NCPATH/apps/spreedme/config/config.php" + exit 0 +fi + +exit diff --git a/apps/talk.sh b/apps/talk.sh new file mode 100755 index 0000000..056e477 --- /dev/null +++ b/apps/talk.sh @@ -0,0 +1,151 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +NC_UPDATE=1 && TURN_INSTALL=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset NC_UPDATE +unset TURN_INSTALL + +print_text_in_color "$ICyan" "Installing Nextcloud Talk..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Must be root +root_check + +# Nextcloud 13 is required. +lowest_compatible_nc 13 + +# Check if Nextcloud is installed +print_text_in_color "$ICyan" "Checking if Nextcloud is installed..." +if ! curl -s https://"${TURN_DOMAIN//\\/}"/status.php | grep -q 'installed":true' +then +msg_box "It seems like Nextcloud is not installed or that you don't use https on: +${TURN_DOMAIN//\\/} +Please install Nextcloud and make sure your domain is reachable, or activate SSL +on your domain to be able to run this script. +If you use the Nextcloud VM you can use the Let's Encrypt script to get SSL and activate your Nextcloud domain. + +When SSL is activated, run these commands from your terminal: +sudo curl -sLO $APP/talk.sh +sudo bash talk.sh" + exit 1 +fi + +# Let the user choose port. TURN_PORT in msg_box is taken from lib.sh and later changed if user decides to. +NONO_PORTS=(22 25 53 80 443 3306 5432 7983 8983 10000) +msg_box "The default port for Talk used in this script is port $TURN_PORT. +You can read more about that port here: https://www.speedguide.net/port.php?port=$TURN_PORT + +You will now be given the option to change this port to something of your own. +Please keep in mind NOT to use the following ports as they are likley to be in use already: +${NONO_PORTS[*]}" + +if [[ "yes" == $(ask_yes_or_no "Do you want to change port?") ]] +then + while true + do + # Ask for port +cat << ENTERDOMAIN ++---------------------------------------------------------------+ +| Please enter the port you will use for Nextcloud Talk: | ++---------------------------------------------------------------+ +ENTERDOMAIN + echo + read -r TURN_PORT + echo + if [[ "yes" == $(ask_yes_or_no "Is this correct? $TURN_PORT") ]] + then + break + fi + done +fi + +containsElement () { + local e match="$1" + shift + for e; do [[ "$e" == "$match" ]] && return 0; done + return 1 +} + +if containsElement "$TURN_PORT" "${NONO_PORTS[@]}" +then + msg_box "You have to choose another port. Please start over." + exit 1 +fi + +# Install TURN +check_command install_if_not coturn +check_command sed -i '/TURNSERVER_ENABLED/c\TURNSERVER_ENABLED=1' /etc/default/coturn + +# Generate $TURN_CONF +cat << TURN_CREATE > "$TURN_CONF" +tls-listening-port=$TURN_PORT +fingerprint +lt-cred-mech +use-auth-secret +static-auth-secret=$TURN_SECRET +realm=$TURN_DOMAIN +total-quota=100 +bps-capacity=0 +stale-nonce +cert=$CERTFILES/$TURN_DOMAIN/cert.pem +pkey=$CERTFILES/$TURN_DOMAIN/privkey.pem +dh-file=$CERTFILES/$TURN_DOMAIN/dhparam.pem +cipher-list="ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5" +no-loopback-peers +no-multicast-peers +no-tlsv1 +no-tlsv1_1 +no-stdout-log +simple-log +log-file=/var/log/turnserver.log +TURN_CREATE +if [ -f "$TURN_CONF" ]; +then + print_text_in_color "$IGreen" "$TURN_CONF was successfully created." +else + print_text_in_color "$IRed" "Unable to create $TURN_CONF, exiting..." + print_text_in_color "$IRed" "Please report this issue here $ISSUES" + exit 1 +fi + +# Restart the TURN server +check_command systemctl restart coturn + +# Warn user to open port +msg_box "You have to open $TURN_PORT TCP/UDP in your firewall or your TURN/STUN server won't work! +After you hit OK the script will check for the firewall and eventually exit on failure. + +To run again the setup, after fixing your firewall: +sudo -sLO $APP/talk.sh +sudo bash talk.sh" + +# Check if the port is open +check_open_port "$TURN_PORT" "$TURN_DOMAIN" + +# Enable Spreed (Talk) +STUN_SERVERS_STRING="[\"$TURN_DOMAIN:$TURN_PORT\"]" +TURN_SERVERS_STRING="[{\"server\":\"$TURN_DOMAIN:$TURN_PORT\",\"secret\":\"$TURN_SECRET\",\"protocols\":\"udp,tcp\"}]" +if [ ! -d "$NC_APPS_PATH"/spreed ] +then + install_and_enable_app spreed + occ_command config:app:set spreed stun_servers --value="$STUN_SERVERS_STRING" --output json + occ_command config:app:set spreed turn_servers --value="$TURN_SERVERS_STRING" --output json + chown -R www-data:www-data "$NC_APPS_PATH" +fi + +if [ -d "$NC_APPS_PATH"/spreed ] +then +msg_box "Nextcloud Talk is now installed. For more information about Nextcloud Talk and its mobile apps visit: +https://nextcloud.com/talk/" +fi + +exit diff --git a/apps/tmbitwarden.sh b/apps/tmbitwarden.sh new file mode 100755 index 0000000..aa35782 --- /dev/null +++ b/apps/tmbitwarden.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +print_text_in_color "$ICyan" "Installing Bitwarden password manager..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +msg_box "Bitwarden is a password manager that is seperate from Nextcloud, though we provide this service because it's self hosted and secure. + +If you just want to run Bitwarden locally (not connecting your smartphone) then you can use 'localhost' as domain. +If you on the other hand want to run this on a domain, then please create a DNS record and point it to this server. +In the process of setting up Bitwarden you will be asked to generate an SSL cert with Let's Enrypt so no need to get your own prior to this setup. + +The script is based on this documentation: https://help.bitwarden.com/article/install-on-premise/ +It's a good idea to read that before you start this script. + +Please also report any issues regarding this script setup to $ISSUES" + +msg_box "The necessary preparations to run expose Bitwarden to the internet are: +1. The HTTP proxy and HTTPS ports for Bitwarden are 8080 and 8443, please open those ports before running this script. +2. Please create a DNS record and point that to this server. +3. Raise the amount of RAM to this server to at least 3 GB." + +if [[ "no" == $(ask_yes_or_no "Have you made the necessary preparations?") ]] +then +msg_box "OK, please do the necessary preparations before you run this script and then simply run it again once you're done. +The script is located at: $SCRIPTS/apps/tmbitwarden.sh" + exit +else + sleep 0.1 +fi + +# Test RAM size (3 GB min) + CPUs (min 2) +ram_check 3 Bitwarden +cpu_check 2 Bitwarden + +# Install Docker +install_docker +install_if_not docker-compose + +# Stop Apache to not conflict when LE is run +check_command systemctl stop apache2.service + +# Install Bitwarden +install_if_not curl +cd /root +curl_to_dir "https://raw.githubusercontent.com/bitwarden/core/master/scripts" "bitwarden.sh" "/root" +chmod +x /root/bitwarden.sh +check_command ./bitwarden.sh install +sed -i "s|http_port.*|http_port: 8080|g" /root/bwdata/config.yml +sed -i "s|https_port.*|https_port: 8443|g" /root/bwdata/config.yml +check_command ./bitwarden.sh rebuild +check_command ./bitwarden.sh start +if check_command ./bitwarden.sh updatedb +then +msg_box "Bitwarden was sucessfully installed! Please visit $(grep 'url:' /root/bwdata/config.yml | awk '{print$2}'):8443 to setup your account." +else +msg_box "Bitwarden installation failed! We will now remove necessary configs to be able to run this script again" + rm -rf /root/bwdata/ +fi + +# Start Apache2 +check_command systemctl start apache2.service diff --git a/apps/webmin.sh b/apps/webmin.sh new file mode 100755 index 0000000..e45c476 --- /dev/null +++ b/apps/webmin.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +print_text_in_color "$ICyan" "Installing Webmin..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +# Install packages for Webmin +install_if_not apt-transport-https +install_if_not perl +install_if_not libnet-ssleay-perl +install_if_not openssl +install_if_not libauthen-pam-perl +install_if_not libpam-runtime +install_if_not libio-pty-perl +install_if_not apt-show-versions +install_if_not python + +# Install Webmin +if curl -fsSL http://www.webmin.com/jcameron-key.asc | sudo apt-key add - +then + echo "deb https://download.webmin.com/download/repository sarge contrib" > /etc/apt/sources.list.d/webmin.list + apt update -q4 & spinner_loading + install_if_not webmin +fi + +exit diff --git a/issue_template.md b/issue_template.md new file mode 100755 index 0000000..6c0bcde --- /dev/null +++ b/issue_template.md @@ -0,0 +1,53 @@ + +## Steps to reproduce +1. +2. +3. + +## Expected behaviour +Tell us what should happen + +## Actual behaviour +Tell us what happens instead + +## Server configuration + +**Nextcloud server version:** (see your admin page) + +**Server OS** (Ubuntu server is default) + +**How did you install the VM?** (Scripted install from master **OR** Released version) + +## Network +**Do you use DHCP?** + +**Is port 80 and/or 443 open?** + +## Logs / Screenshots + + +#### Log file (/mnt/ncdata/nextcloud.log) +``` +Insert your nextcloud.log file here +``` + +#### Installation log (command output) +``` +Insert the CLI output here +``` + +#### Screenshoots + diff --git a/lets-encrypt/activate-ssl.sh b/lets-encrypt/activate-ssl.sh new file mode 100755 index 0000000..1e86152 --- /dev/null +++ b/lets-encrypt/activate-ssl.sh @@ -0,0 +1,300 @@ +#!/bin/bash +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +# Information +msg_box "Important! Please read this: + +This script will install SSL from Let's Encrypt. +It's free of charge, and very easy to maintain. + +Before we begin the installation you need to have +a domain that the SSL certs will be valid for. +If you don't have a domain yet, get one before +you run this script! + +You also have to open port 80+443 against this VMs +IP address: $ADDRESS - do this in your router/FW. +Here is a guide: https://goo.gl/Uyuf65 + +You can find the script here: $SCRIPTS/activate-ssl.sh +and you can run it after you got a domain. + +Please don't run this script if you don't have +a domain yet. You can get one for a fair price here: +https://store.binero.se/?lang=en-US" + +if [[ "no" == $(ask_yes_or_no "Are you sure you want to continue?") ]] +then +msg_box "OK, but if you want to run this script later, +just type: sudo bash $SCRIPTS/activate-ssl.sh" + exit +fi + +if [[ "no" == $(ask_yes_or_no "Have you forwarded port 80+443 in your router?") ]] +then +msg_box "OK, but if you want to run this script later, +just type: sudo bash /var/scripts/activate-ssl.sh" + exit +fi + +if [[ "yes" == $(ask_yes_or_no "Do you have a domain that you will use?") ]] +then + sleep 1 +else +msg_box "OK, but if you want to run this script later, +just type: sudo bash /var/scripts/activate-ssl.sh" + exit +fi + +echo +while true +do +# Ask for domain name +cat << ENTERDOMAIN ++---------------------------------------------------------------+ +| Please enter the domain name you will use for Nextcloud: | +| Like this: example.com, or nextcloud.example.com | ++---------------------------------------------------------------+ +ENTERDOMAIN +echo +read -r domain +echo +if [[ "yes" == $(ask_yes_or_no "Is this correct? $domain") ]] +then + break +fi +done + +# Check if $domain exists and is reachable +echo +print_text_in_color "$ICyan" "Checking if $domain exists and is reachable..." +domain_check_200 "$domain" + +# Check if port is open with NMAP +sed -i "s|127.0.1.1.*|127.0.1.1 $domain nextcloud|g" /etc/hosts +network_ok +check_open_port 80 "$domain" +check_open_port 443 "$domain" + +# Fetch latest version of test-new-config.sh +check_command download_le_script test-new-config + +# Install certbot (Let's Encrypt) +install_certbot + +#Fix issue #28 +ssl_conf="/etc/apache2/sites-available/"$domain.conf"" + +# DHPARAM +DHPARAMS="$CERTFILES/$domain/dhparam.pem" + +# Check if "$ssl.conf" exists, and if, then delete +if [ -f "$ssl_conf" ] +then + rm -f "$ssl_conf" +fi + +# Generate nextcloud_ssl_domain.conf +if [ ! -f "$ssl_conf" ] +then + touch "$ssl_conf" + print_text_in_color "$IGreen" "$ssl_conf was successfully created." + sleep 2 + cat << SSL_CREATE > "$ssl_conf" + + RewriteEngine On + RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L] + + + + + Header add Strict-Transport-Security: "max-age=15768000;includeSubdomains" + SSLEngine on + SSLCompression off + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLHonorCipherOrder on + SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 + SSLSessionTickets off + +### YOUR SERVER ADDRESS ### + + ServerAdmin admin@$domain + ServerName $domain + +### SETTINGS ### + + SetHandler "proxy:unix:/run/php/php$PHPVER-fpm.nextcloud.sock|fcgi://localhost" + + + DocumentRoot $NCPATH + + + Options Indexes FollowSymLinks + AllowOverride All + Require all granted + Satisfy Any + + + + Dav off + + + SetEnv HOME $NCPATH + SetEnv HTTP_HOME $NCPATH + + # The following lines prevent .htaccess and .htpasswd files from being + # viewed by Web clients. + + Require all denied + + + # Disable HTTP TRACE method. + TraceEnable off + # Disable HTTP TRACK method. + RewriteEngine On + RewriteCond %{REQUEST_METHOD} ^TRACK + RewriteRule .* - [R=405,L] + + # Avoid "Sabre\DAV\Exception\BadRequest: expected filesize XXXX got XXXX" + + RequestReadTimeout body=0 + + +### LOCATION OF CERT FILES ### + + SSLCertificateChainFile $CERTFILES/$domain/chain.pem + SSLCertificateFile $CERTFILES/$domain/cert.pem + SSLCertificateKeyFile $CERTFILES/$domain/privkey.pem + SSLOpenSSLConfCmd DHParameters $DHPARAMS + + + +### EXTRAS ### + SSLUseStapling On + SSLStaplingCache "shmcb:logs/ssl_stapling(32768)" +SSL_CREATE +fi + +# Check if PHP-FPM is installed and if not, then remove PHP-FPM related lines from config +if [ ! -f "$PHP_POOL_DIR"/nextcloud.conf ] +then + sed -i "s| /tmp/le_test +else + echo "fail" > /tmp/le_test +fi +} +tls-alpn-01() { +if eval "certbot certonly --preferred-challenges tls-alpn-01 $default_le" +then + echo "success" > /tmp/le_test +else + echo "fail" > /tmp/le_test +fi +} +dns() { +if eval "certbot certonly --manual --manual-public-ip-logging-ok --preferred-challenges dns $default_le" +then + echo "success" > /tmp/le_test +else + echo "fail" > /tmp/le_test +fi +} + +methods=(standalone dns) + +create_config() { +# $1 = method +local method="$1" +# Check if $CERTFILES exists +if [ -d "$CERTFILES" ] + then + # Generate DHparams chifer + if [ ! -f "$DHPARAMS" ] + then + openssl dhparam -dsaparam -out "$DHPARAMS" 4096 + fi + # Activate new config + check_command bash "$SCRIPTS/test-new-config.sh" "$domain.conf" + exit +fi +} + +attempts_left() { +local method="$1" +if [ "$method" == "standalone" ] +then + printf "%b" "${ICyan}It seems like no certs were generated, we will do 1 more try.\n${Color_Off}" + any_key "Press any key to continue..." +#elif [ "$method" == "tls-alpn-01" ] +#then +# printf "%b" "${ICyan}It seems like no certs were generated, we will do 1 more try.\n${Color_Off}" +# any_key "Press any key to continue..." +elif [ "$method" == "dns" ] +then + printf "%b" "${IRed}It seems like no certs were generated, please check your DNS and try again.\n${Color_Off}" + any_key "Press any key to continue..." +fi +} + +# Generate the cert +for f in "${methods[@]}"; do "$f" +if [ "$(grep 'success' /tmp/le_test)" == 'success' ]; then + rm -f /tmp/le_test + create_config "$f" +else + rm -f /tmp/le_test + attempts_left "$f" +fi +done + +# Failed +msg_box "Sorry, last try failed as well. :/ + +The script is located in $SCRIPTS/activate-ssl.sh +Please try to run it again some other time with other settings. + +There are different configs you can try in Let's Encrypt's user guide: +https://letsencrypt.readthedocs.org/en/latest/index.html +Please check the guide for further information on how to enable SSL. + +This script is developed on GitHub, feel free to contribute: +https://github.com/nextcloud/vm + +The script will now do some cleanup and revert the settings." + +# Cleanup +apt remove certbot -y +apt autoremove -y +clear diff --git a/lets-encrypt/test-new-config.sh b/lets-encrypt/test-new-config.sh new file mode 100755 index 0000000..98ee0f4 --- /dev/null +++ b/lets-encrypt/test-new-config.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Activate the new config +printf "${Color_Off}We will now test that everything is OK\n" +any_key "Press any key to continue... " +a2ensite "$1" +a2dissite nextcloud_ssl_domain_self_signed.conf +a2dissite nextcloud_http_domain_self_signed.conf +a2dissite 000-default.conf +if restart_webserver +then +msg_box "New settings works! SSL is now activated and OK! + +This cert will expire in 90 days if you don't renew it. +There are several ways of renewing this cert and here are some tips and tricks: +https://goo.gl/c1JHR0 + +To do your job a little bit easier we have added a autorenew script as a cronjob. +If you need to edit the crontab please type: crontab -u root -e +If you need to edit the script itself, please check: $SCRIPTS/letsencryptrenew.sh + +Feel free to contribute to this project: https://goo.gl/3fQD65" + crontab -u root -l | { cat; echo "3 */12 * * * $SCRIPTS/letsencryptrenew.sh"; } | crontab -u root - + +FQDOMAIN=$(grep -m 1 "ServerName" "/etc/apache2/sites-enabled/$1" | awk '{print $2}') +if [ "$(hostname)" != "$FQDOMAIN" ] +then + print_text_in_color "$ICyan" "Setting hostname to $FQDOMAIN..." + sudo sh -c "echo 'ServerName $FQDOMAIN' >> /etc/apache2/apache2.conf" + sudo hostnamectl set-hostname "$FQDOMAIN" + # Change /etc/hosts as well + sed -i "s|127.0.1.1.*|127.0.1.1 $FQDOMAIN $(hostname -s)|g" /etc/hosts + # And in the php-fpm pool conf + sed -i "s|env\[HOSTNAME\] = .*|env[HOSTNAME] = $(hostname -f)|g" "$PHP_POOL_DIR"/nextcloud.conf +fi + +# Set trusted domains +run_static_script trusted + +add_crontab_le() { +# shellcheck disable=SC2016 +DATE='$(date +%Y-%m-%d_%H:%M)' +cat << CRONTAB > "$SCRIPTS/letsencryptrenew.sh" +#!/bin/sh +if ! certbot renew --quiet --no-self-upgrade > /var/log/letsencrypt/renew.log 2>&1 ; then + echo "Let's Encrypt FAILED!"--$DATE >> /var/log/letsencrypt/cronjob.log +else + echo "Let's Encrypt SUCCESS!"--$DATE >> /var/log/letsencrypt/cronjob.log +fi + +# Check if service is running +if ! pgrep apache2 > /dev/null +then + service apache2 start +fi +CRONTAB +} +add_crontab_le + +# Makeletsencryptrenew.sh executable +chmod +x $SCRIPTS/letsencryptrenew.sh + +# Cleanup +rm -f $SCRIPTS/test-new-config.sh +rm -f $SCRIPTS/activate-ssl.sh +rm -f /var/www/index.php + +else +# If it fails, revert changes back to normal + a2dissite "$1" + a2ensite nextcloud_ssl_domain_self_signed.conf + a2ensite nextcloud_http_domain_self_signed.conf + a2ensite 000-default.conf + restart_webserver + printf "${ICyan}Couldn't load new config, reverted to old settings. Self-signed SSL is OK!${Color_Off}\n" + any_key "Press any key to continue... " + exit 1 +fi diff --git a/lib.sh b/lib.sh new file mode 100755 index 0000000..7df6db0 --- /dev/null +++ b/lib.sh @@ -0,0 +1,1071 @@ +#!/bin/bash +# shellcheck disable=2034,2059 +true +# see https://github.com/koalaman/shellcheck/wiki/Directive + +## VARIABLES + +# Dirs +SCRIPTS=/var/scripts +NCPATH=/var/www/nextcloud +HTML=/var/www +NCDATA=/mnt/ncdata +SNAPDIR=/var/snap/spreedme +GPGDIR=/tmp/gpg +BACKUP=/mnt/NCBACKUP +RORDIR=/opt/es/ +NC_APPS_PATH=$NCPATH/apps +VMLOGS=/var/log/nextcloud + +# Ubuntu OS +DISTRO=$(lsb_release -sd | cut -d ' ' -f 2) +KEYBOARD_LAYOUT=$(localectl status | grep "Layout" | awk '{print $3}') +# Network +[ -n "$FIRST_IFACE" ] && IFACE=$(lshw -c network | grep "logical name" | awk '{print $3; exit}') +IFACE2=$(ip -o link show | awk '{print $2,$9}' | grep 'UP' | cut -d ':' -f 1) +[ -n "$CHECK_CURRENT_REPO" ] && REPO=$(apt-get update | grep -m 1 Hit | awk '{ print $2}') +ADDRESS=$(hostname -I | cut -d ' ' -f 1) +# WANIP4=$(dig +short myip.opendns.com @resolver1.opendns.com) # as an alternative +WANIP4=$(curl -s -k -m 5 https://ipv4bot.whatismyipaddress.com) +[ -n "$LOAD_IP6" ] && WANIP6=$(curl -s -k -m 5 https://ipv6bot.whatismyipaddress.com) +INTERFACES="/etc/netplan/01-netcfg.yaml" +GATEWAY=$(ip route | grep default | awk '{print $3}') +DNS1="9.9.9.9" +DNS2="149.112.112.112" +# Repo +GITHUB_REPO="https://raw.githubusercontent.com/nextcloud/vm/master" +STATIC="$GITHUB_REPO/static" +LETS_ENC="$GITHUB_REPO/lets-encrypt" +APP="$GITHUB_REPO/apps" +NCREPO="https://download.nextcloud.com/server/releases" +ISSUES="https://github.com/nextcloud/vm/issues" +# User information +NCPASS=nextcloud +NCUSER=ncadmin +UNIXUSER=$SUDO_USER +UNIXUSER_PROFILE="/home/$UNIXUSER/.bash_profile" +ROOT_PROFILE="/root/.bash_profile" +# Database +SHUF=$(shuf -i 25-29 -n 1) +MARIADB_PASS=$(tr -dc "a-zA-Z0-9@#*=" < /dev/urandom | fold -w "$SHUF" | head -n 1) +NEWMARIADBPASS=$(tr -dc "a-zA-Z0-9@#*=" < /dev/urandom | fold -w "$SHUF" | head -n 1) +[ -n "$NCDB" ] && NCCONFIGDB=$(grep "dbname" $NCPATH/config/config.php | awk '{print $3}' | sed "s/[',]//g") +ETCMYCNF=/etc/mysql/my.cnf +MYCNF=/root/.my.cnf +[ -n "$MYCNFPW" ] && MARIADBMYCNFPASS=$(grep "password" $MYCNF | sed -n "/password/s/^password='\(.*\)'$/\1/p") +PGDB_PASS=$(tr -dc "a-zA-Z0-9@#*=" < /dev/urandom | fold -w "$SHUF" | head -n 1) +NEWPGPASS=$(tr -dc "a-zA-Z0-9@#*=" < /dev/urandom | fold -w "$SHUF" | head -n 1) +[ -n "$NCDB" ] && NCCONFIGDB=$(grep "dbname" $NCPATH/config/config.php | awk '{print $3}' | sed "s/[',]//g") +[ -n "$NCDBPASS" ] && NCCONFIGDBPASS=$(grep "dbpassword" $NCPATH/config/config.php | awk '{print $3}' | sed "s/[',]//g") +# Path to specific files +SECURE="$SCRIPTS/setup_secure_permissions_nextcloud.sh" +SSL_CONF="/etc/apache2/sites-available/nextcloud_ssl_domain_self_signed.conf" +HTTP_CONF="/etc/apache2/sites-available/nextcloud_http_domain_self_signed.conf" +# Nextcloud version +[ -n "$NC_UPDATE" ] && CURRENTVERSION=$(sudo -u www-data php $NCPATH/occ status | grep "versionstring" | awk '{print $3}') +[ -n "$NC_UPDATE" ] && NCVERSION=$(curl -s -m 900 $NCREPO/ | sed --silent 's/.*href="nextcloud-\([^"]\+\).zip.asc".*/\1/p' | sort --version-sort | tail -1) +[ -n "$NC_UPDATE" ] && STABLEVERSION="nextcloud-$NCVERSION" +[ -n "$NC_UPDATE" ] && NCMAJOR="${NCVERSION%%.*}" +[ -n "$NC_UPDATE" ] && NCBAD=$((NCMAJOR-2)) +# Keys +OpenPGP_fingerprint='28806A878AE423A28372792ED75899B9A724937A' +# OnlyOffice URL +[ -n "$OO_INSTALL" ] && SUBDOMAIN=$(whiptail --title "T&M Hansson IT OnlyOffice" --inputbox "OnlyOffice subdomain eg: office.yourdomain.com\n\nNOTE: This domain must be different than your Nextcloud domain. They can however be hosted on the same server, but would require seperate DNS entries." "$WT_HEIGHT" "$WT_WIDTH" 3>&1 1>&2 2>&3) +# Nextcloud Main Domain +[ -n "$OO_INSTALL" ] && NCDOMAIN=$(whiptail --title "T&M Hansson IT OnlyOffice" --inputbox "Nextcloud domain, make sure it looks like this: cloud\\.yourdomain\\.com" "$WT_HEIGHT" "$WT_WIDTH" cloud\\.yourdomain\\.com 3>&1 1>&2 2>&3) +# Collabora Docker URL +[ -n "$COLLABORA_INSTALL" ] && SUBDOMAIN=$(whiptail --title "T&M Hansson IT Collabora" --inputbox "Collabora subdomain eg: office.yourdomain.com\n\nNOTE: This domain must be different than your Nextcloud domain. They can however be hosted on the same server, but would require seperate DNS entries." "$WT_HEIGHT" "$WT_WIDTH" 3>&1 1>&2 2>&3) +# Nextcloud Main Domain +[ -n "$COLLABORA_INSTALL" ] && NCDOMAIN=$(whiptail --title "T&M Hansson IT Collabora" --inputbox "Nextcloud domain, make sure it looks like this: cloud\\.yourdomain\\.com" "$WT_HEIGHT" "$WT_WIDTH" cloud\\.yourdomain\\.com 3>&1 1>&2 2>&3) +# Letsencrypt +LETSENCRYPTPATH="/etc/letsencrypt" +CERTFILES="$LETSENCRYPTPATH/live" +DHPARAMS="$CERTFILES/$SUBDOMAIN/dhparam.pem" +# Collabora App +HTTPS_CONF="/etc/apache2/sites-available/$SUBDOMAIN.conf" +HTTP2_CONF="/etc/apache2/mods-available/http2.conf" +# PHP-FPM +PHPVER=7.2 +PHP_FPM_DIR=/etc/php/$PHPVER/fpm +PHP_INI=$PHP_FPM_DIR/php.ini +PHP_POOL_DIR=$PHP_FPM_DIR/pool.d +# Adminer +ADMINERDIR=/usr/share/adminer +ADMINER_CONF=/etc/apache2/conf-available/adminer.conf +# Redis +REDIS_CONF=/etc/redis/redis.conf +REDIS_SOCK=/var/run/redis/redis-server.sock +RSHUF=$(shuf -i 30-35 -n 1) +REDIS_PASS=$(tr -dc "a-zA-Z0-9@#*=" < /dev/urandom | fold -w "$RSHUF" | head -n 1) +# Extra security +SPAMHAUS=/etc/spamhaus.wl +ENVASIVE=/etc/apache2/mods-available/mod-evasive.load +APACHE2=/etc/apache2/apache2.conf +# Full text Search +[ -n "$ES_INSTALL" ] && INDEX_USER=$(tr -dc '[:lower:]' < /dev/urandom | fold -w "$SHUF" | head -n 1) +[ -n "$ES_INSTALL" ] && ROREST=$(tr -dc "A-Za-z0-9" < /dev/urandom | fold -w "$SHUF" | head -n 1) +[ -n "$ES_INSTALL" ] && nc_fts="ark74/nc_fts" +[ -n "$ES_INSTALL" ] && fts_es_name="fts_esror" +# Talk +[ -n "$TURN_INSTALL" ] && TURN_CONF="/etc/turnserver.conf" +[ -n "$TURN_INSTALL" ] && TURN_PORT=5349 +[ -n "$TURN_INSTALL" ] && SHUF=$(shuf -i 25-29 -n 1) +[ -n "$TURN_INSTALL" ] && TURN_SECRET=$(tr -dc "a-zA-Z0-9@#*=" < /dev/urandom | fold -w "$SHUF" | head -n 1) +[ -n "$TURN_INSTALL" ] && TURN_DOMAIN=$(sudo -u www-data /var/www/nextcloud/occ config:system:get overwrite.cli.url | sed 's#https://##;s#/##') + +## FUNCTIONS + +# If script is running as root? +# +# Example: +# if is_root +# then +# # do stuff +# else +# print_text_in_color "$IRed" "You are not root..." +# exit 1 +# fi +# +is_root() { + if [[ "$EUID" -ne 0 ]] + then + return 1 + else + return 0 + fi +} + +# Check if root +root_check() { +if ! is_root +then +msg_box "Sorry, you are not root. You now have two options: + +1. With SUDO directly: + a) :~$ sudo bash $SCRIPTS/name-of-script.sh + +2. Become ROOT and then type your command: + a) :~$ sudo -i + b) :~# bash $SCRIPTS/name-of-script.sh + +In both cases above you can leave out $SCRIPTS/ if the script +is directly in your PATH. + +More information can be found here: https://unix.stackexchange.com/a/3064" + exit 1 +fi +} + +debug_mode() { +if [ "$DEBUG" -eq 1 ] +then + set -ex +fi +} + +ask_yes_or_no() { + read -r -p "$1 ([y]es or [N]o): " + case ${REPLY,,} in + y|yes) + echo "yes" + ;; + *) + echo "no" + ;; + esac +} + +msg_box() { +local PROMPT="$1" + whiptail --title "Nextcloud VM - T&M Hansson IT - $(date +"%Y")" --msgbox "${PROMPT}" "$WT_HEIGHT" "$WT_WIDTH" +} + +# Check if process is runnnig: is_process_running dpkg +is_process_running() { +PROCESS="$1" + +while : +do + RESULT=$(pgrep "${PROCESS}") + + if [ "${RESULT:-null}" = null ]; then + break + else + print_text_in_color "$ICyan" "${PROCESS} is running, waiting for it to stop..." + sleep 10 + fi +done +} + +# Checks if site is reachable with a HTTP 200 status +site_200() { +print_text_in_color "$ICyan" "Checking connection..." + CURL_STATUS="$(curl -sSL -w "%{http_code}" "${1}" | tail -1)" + if [[ "$CURL_STATUS" = "200" ]] + then + return 0 + else + print_text_in_color "$IRed" "curl didn't produce a 200 status, is the site reachable?" + return 1 + fi +} + +# Do a DNS lookup and compare the WAN address with the A record +domain_check_200() { + print_text_in_color "$ICyan" "Doing a DNS lookup for ${1}..." + install_if_not dnsutils + + # Try to resolve the domain with nslookup using $DNS as resolver + if nslookup "${1}" $DNS1 >/dev/null 2>&1 + then + print_text_in_color "$IGreen" "DNS seems correct when checking with nslookup!" + else + print_text_in_color "$IRed" "DNS lookup failed with nslookup." + print_text_in_color "$IRed" "Please check your DNS settings! Maybe the domain isn't propagated?" + print_text_in_color "$ICyan" "Please check https://www.whatsmydns.net/#A/${1} if the IP seems correct." + nslookup "${1}" $DNS1 + return 1 + fi + + # Is the DNS record same as the external IP address of the server? + DIG="$(dig +short "${1}" @resolver1.opendns.com)" + if [[ "$DIG" = "$WANIP4" ]] + then + print_text_in_color "$IGreen" "DNS seems correct when checking with dig!" + elif [[ "$DIG" != "$WANIP4" ]] + then +msg_box "DNS lookup failed with dig. The external IP ($WANIP4) address of this server is not the same as the A-record ($DIG). +Please check your DNS settings! Maybe the domain isn't propagated? +Please check https://www.whatsmydns.net/#A/${1} if the IP seems correct." + +msg_box "As you noticed your WAN IP and DNS record doesn't match. This can happen when using DDNS for example, or in some edge cases. +If you feel brave, or are sure that everything is setup correctly, then you can choose to skip this test in the next step. + +You can always contact us for further support if you wish: https://shop.hanssonit.se/product/premium-support-per-30-minutes/" + if [[ "no" == $(ask_yes_or_no "Do you feel brave and want to continue?") ]] + then + exit + fi + fi +} + +# A function to fetch a file with curl to a directory +# 1 = https://example.com +# 2 = name of file +# 3 = directory that the file should end up in +curl_to_dir() { +if [ ! -d "$3" ] +then + mkdir -p "$3" +fi + rm -f "$3"/"$2" + curl -sfL "$1"/"$2" -o "$3"/"$2" +} + +start_if_stopped() { +if ! pgrep "$1" +then + print_text_in_color "$ICyan" "Starting $1..." + check_command service "$1" start +fi +} + +# Warn user that HTTP/2 will be disabled if installing app that use Apache2 PHP instead of PHP-FPM +# E.g: http2_warn Modsecurity +http2_warn() { +msg_box "This VM has HTTP/2 enabled by default. + +If you continue with installing $1, HTTP/2 will be disabled since it's not compatible with the mpm module used by $1. + +This is what Apache will say in the error.log if you enable $1 anyway: +'The mpm module (prefork.c) is not supported by mod_http2. +The mpm determines how things are processed in your server. +HTTP/2 has more demands in this regard and the currently selected mpm will just not do. +This is an advisory warning. Your server will continue to work, but the HTTP/2 protocol will be inactive.'" + +if [[ "no" == $(ask_yes_or_no "Do you really want to enable $1 anyway?") ]] +then + exit 1 +fi +} + +calculate_php_fpm() { +# Minimum amount of max children (lower than this won't work with 2 GB RAM) +min_max_children=8 +# If start servers are lower than this then it's likely that there are room for max_spare_servers +min_start_servers=20 +# Maximum amount of children is only set if the min_start_servers value are met +min_max_spare_servers=35 + +# Calculate the sum of the current values +CURRENT_START="$(grep pm.start_servers "$PHP_POOL_DIR"/nextcloud.conf | awk '{ print $3}')" +CURRENT_MAX="$(grep pm.max_spare_servers "$PHP_POOL_DIR"/nextcloud.conf | awk '{ print $3}')" +CURRENT_MIN="$(grep pm.min_spare_servers "$PHP_POOL_DIR"/nextcloud.conf | awk '{ print $3}')" +CURRENT_SUM="$((CURRENT_START + CURRENT_MAX + CURRENT_MIN))" + +# Calculate max_children depending on RAM +# Tends to be between 30-50MB per children +average_php_memory_requirement=50 +available_memory=$(awk '/MemAvailable/ {printf "%d", $2/1024}' /proc/meminfo) +PHP_FPM_MAX_CHILDREN=$((available_memory/average_php_memory_requirement)) + +# Lowest possible value is 8 +print_text_in_color "$ICyan" "Automatically configures pm.max_children for php-fpm..." +if [ $PHP_FPM_MAX_CHILDREN -lt $min_max_children ] +then +msg_box "The current max_children value available to set is $PHP_FPM_MAX_CHILDREN, and with that value PHP-FPM won't function properly. +The minimum value is 8, and the value is calculated depening on how much RAM you have left to use in the system. + +The absolute minimum amount of RAM required to run the VM is 2 GB, but we recomend 4 GB. + +You now have two choices: +1. Import this VM again, raise the amount of RAM with at least 1 GB, and then run this script again, + installing it in the same way as you did before. +2. Import this VM again without raising the RAM, but don't install any of the following apps: + 1) Collabora + 2) OnlyOffice + 3) Full Text Search + +This script will now exit. +The installation was not successful, sorry for the inconvenience. + +If you think this is a bug, please report it to $ISSUES" +exit 1 +else + check_command sed -i "s|pm.max_children.*|pm.max_children = $PHP_FPM_MAX_CHILDREN|g" "$PHP_POOL_DIR"/nextcloud.conf + print_text_in_color "$IGreen" "pm.max_children was set to $PHP_FPM_MAX_CHILDREN" + # Check if the sum of all the current values are more than $PHP_FPM_MAX_CHILDREN and only continue it is + if [ $PHP_FPM_MAX_CHILDREN -gt $CURRENT_SUM ] + then + # Set pm.max_spare_servers + if [ $PHP_FPM_MAX_CHILDREN -ge $min_max_spare_servers ] + then + if [ "$(grep pm.start_servers "$PHP_POOL_DIR"/nextcloud.conf | awk '{ print $3}')" -lt $min_start_servers ] + then + check_command sed -i "s|pm.max_spare_servers.*|pm.max_spare_servers = $((PHP_FPM_MAX_CHILDREN - 30))|g" "$PHP_POOL_DIR"/nextcloud.conf + print_text_in_color "$IGreen" "pm.max_spare_servers was set to $((PHP_FPM_MAX_CHILDREN - 30))" + fi + fi + fi +fi + +# If $PHP_FPM_MAX_CHILDREN is lower than the current sum of all values, revert to default settings +if [ $PHP_FPM_MAX_CHILDREN -lt $CURRENT_SUM ] +then + check_command sed -i "s|pm.max_children.*|pm.max_children = $PHP_FPM_MAX_CHILDREN|g" "$PHP_POOL_DIR"/nextcloud.conf + check_command sed -i "s|pm.start_servers.*|pm.start_servers = 3|g" "$PHP_POOL_DIR"/nextcloud.conf + check_command sed -i "s|pm.min_spare_servers.*|pm.min_spare_servers = 2|g" "$PHP_POOL_DIR"/nextcloud.conf + check_command sed -i "s|pm.max_spare_servers.*|pm.max_spare_servers = 3|g" "$PHP_POOL_DIR"/nextcloud.conf + print_text_in_color "$ICyan" "All PHP-INI values were set back to default values as the value for pm.max_children ($PHP_FPM_MAX_CHILDREN) was lower than the sum of all the current values ($CURRENT_SUM)" + print_text_in_color "$ICyan" "Please run this again to set optimal values" +fi +restart_webserver +} + +test_connection() { +# Install dnsutils if not existing +if ! dpkg-query -W -f='${Status}' "dnsutils" | grep -q "ok installed" +then + apt update -q4 & spinner_loading && apt install dnsutils -y +fi +# Install network-manager if not existing +if ! dpkg-query -W -f='${Status}' "network-manager" | grep -q "ok installed" +then + apt update -q4 & spinner_loading && apt install network-manager -y +fi +check_command service network-manager restart +ip link set "$IFACE" down +sleep 2 +ip link set "$IFACE" up +sleep 2 +print_text_in_color "$ICyan" "Checking connection..." +check_command service network-manager restart +sleep 2 +if nslookup github.com +then + print_text_in_color "$IGreen" "Online!" +elif ! nslookup github.com +then + print_text_in_color "$ICyan" "Trying to restart networking service..." + check_command service networking restart && sleep 2 + if nslookup github.com + then + print_text_in_color "$IGreen" "Online!" + fi +else + if ! nslookup github.com + then +msg_box "Network NOT OK. You must have a working network connection to run this script +If you think that this is a bug, please report it to https://github.com/nextcloud/vm/issues." + exit 1 + fi +fi +} + +restart_webserver() { +check_command systemctl restart apache2 +if is_this_installed php"$PHPVER"-fpm +then + check_command systemctl restart php"$PHPVER"-fpm.service +fi + +} + +# Install certbot (Let's Encrypt) +install_certbot() { +certbot --version 2> /dev/null +LE_IS_AVAILABLE=$? +if [ $LE_IS_AVAILABLE -eq 0 ] +then + certbot --version 2> /dev/null +else + print_text_in_color "$ICyan" "Installing certbot (Let's Encrypt)..." + apt update -q4 & spinner_loading + install_if_not software-properties-common + add-apt-repository ppa:certbot/certbot -y + apt update -q4 & spinner_loading + install_if_not certbot + apt update -q4 & spinner_loading + apt dist-upgrade -y +fi +} + +# Let's Encrypt for subdomains +le_subdomain() { +a2dissite 000-default.conf +service apache2 reload +certbot certonly --standalone --pre-hook "service apache2 stop" --post-hook "service apache2 start" --agree-tos --rsa-key-size 4096 -d "$SUBDOMAIN" +} + +# Check if port is open # check_open_port 443 domain.example.com +check_open_port() { +print_text_in_color "$ICyan" "Checking if port ${1} is open with https://ports.yougetsignal.com..." +install_if_not curl +# WAN Adress +if check_command curl -s -H 'Cache-Control: no-cache' 'https://ports.yougetsignal.com/check-port.php' --data "remoteAddress=${WANIP4}&portNumber=${1}" | grep -q "is open on" +then + print_text_in_color "$IGreen" "Port ${1} is open on ${WANIP4}!" +# Domain name +elif check_command curl -s -H 'Cache-Control: no-cache' 'https://ports.yougetsignal.com/check-port.php' --data "remoteAddress=${2}&portNumber=${1}" | grep -q "is open on" +then + print_text_in_color "$IGreen" "Port ${1} is open on ${2}!" +else + msg_box "Port $1 is not open on either ${WANIP4} or ${2}.\n\nPlease follow this guide to open ports in your router or firewall:\nhttps://www.techandme.se/open-port-80-443/" + any_key "Press any key to exit..." + exit 1 +fi +} + +check_distro_version() { +# Check Ubuntu version +print_text_in_color "$ICyan" "Checking server OS and version..." +if lsb_release -c | grep -ic "bionic" &> /dev/null +then + OS=1 +elif lsb_release -i | grep -ic "Ubuntu" &> /dev/null +then + OS=1 +elif uname -a | grep -ic "bionic" &> /dev/null +then + OS=1 +elif uname -v | grep -ic "Ubuntu" &> /dev/null +then + OS=1 +fi + +if [ "$OS" != 1 ] +then +msg_box "Ubuntu Server is required to run this script. +Please install that distro and try again. + +You can find the download link here: https://www.ubuntu.com/download/server" + exit 1 +fi + +if ! version 18.04 "$DISTRO" 18.04.4; then +msg_box "Ubuntu version $DISTRO must be between 18.04 - 18.04.4" + exit 1 +fi +} + +# Check if program is installed (stop_if_installed apache2) +stop_if_installed() { +if [ "$(dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed")" == "1" ] +then + print_text_in_color "$IRed" "${1} is installed, it must be a clean server." + exit 1 +fi +} + +# Check if program is installed (is_this_installed apache2) +is_this_installed() { +if dpkg-query -W -f='${Status}' "${1}" | grep -q "ok installed" +then + return 0 +else + return 1 +fi +} + +# Install_if_not program +install_if_not() { +if ! dpkg-query -W -f='${Status}' "${1}" | grep -q "ok installed" +then + apt update -q4 & spinner_loading && apt install "${1}" -y +fi +} + +# Test RAM size +# Call it like this: ram_check [amount of min RAM in GB] [for which program] +# Example: ram_check 2 Nextcloud +ram_check() { +mem_available="$(awk '/MemTotal/{print $2}' /proc/meminfo)" +if [ "${mem_available}" -lt "$((${1}*1002400))" ] +then + print_text_in_color "$IRed" "Error: ${1} GB RAM required to install ${2}!" >&2 + print_text_in_color "$IRed" "Current RAM is: ("$((mem_available/1002400))" GB)" >&2 + sleep 3 + msg_box "If you want to bypass this check you could do so by commenting out (# before the line) 'ram_check X' in the script that you are trying to run. + + In nextcloud_install_production.sh you can find the check somewhere around line #34. + + Please notice that things may be veery slow and not work as expeced. YOU HAVE BEEN WARNED!" + exit 1 +else + print_text_in_color "$IGreen" "RAM for ${2} OK! ($((mem_available/1002400)) GB)" +fi +} + +# Test number of CPU +# Call it like this: cpu_check [amount of min CPU] [for which program] +# Example: cpu_check 2 Nextcloud +cpu_check() { +nr_cpu="$(nproc)" +if [ "${nr_cpu}" -lt "${1}" ] +then + print_text_in_color "$IRed" "Error: ${1} CPU required to install ${2}!" >&2 + print_text_in_color "$IRed" "Current CPU: ($((nr_cpu)))" >&2 + sleep 3 + exit 1 +else + print_text_in_color "$IGreen" "CPU for ${2} OK! ($((nr_cpu)))" +fi +} + +check_command() { + if ! "$@"; + then + print_text_in_color "$ICyan" "Sorry but something went wrong. Please report this issue to $ISSUES and include the output of the error message. Thank you!" + print_text_in_color "$IRed" "$* failed" + exit 1 + fi +} + +# Example: occ_command 'maintenance:mode --on' +occ_command() { +check_command sudo -u www-data php "$NCPATH"/occ "$@"; +} + +network_ok() { + print_text_in_color "$ICyan" "Testing if network is OK..." + install_if_not network-manager + if ! service network-manager restart > /dev/null + then + service networking restart > /dev/null + fi + sleep 5 && site_200 github.com +} + +# Whiptail auto-size +calc_wt_size() { + WT_HEIGHT=17 + WT_WIDTH=$(tput cols) + + if [ -z "$WT_WIDTH" ] || [ "$WT_WIDTH" -lt 60 ]; then + WT_WIDTH=80 + fi + if [ "$WT_WIDTH" -gt 178 ]; then + WT_WIDTH=120 + fi + WT_MENU_HEIGHT=$((WT_HEIGHT-7)) + export WT_MENU_HEIGHT +} + +install_and_enable_app() { +# Download and install $1 +if [ ! -d "$NC_APPS_PATH/$1" ] +then + print_text_in_color "$ICyan" "Installing $1..." + # occ_command not possible here because it uses check_command and will exit if occ_command fails + installcmd="$(sudo -u www-data php ${NCPATH}/occ app:install "$1")" + if grep 'not compatible' <<< "$installcmd" + then +msg_box "The $1 app could not be installed. +It's probably not compatible with $(occ_command -V). + +You can try to install the app manually after the script has finished, +or when a new version of the app is released with the following command: + +'sudo -u www-data php ${NCPATH}/occ app:install $1'" + rm -Rf "$NCPATH/apps/$1" + else + # Enable $1 + if [ -d "$NC_APPS_PATH/$1" ] + then + occ_command app:enable "$1" + chown -R www-data:www-data "$NC_APPS_PATH" + fi + fi +else + print_text_in_color "$ICyan" "It seems like $1 is installed already, trying to enable it..." + # occ_command not possible here because it uses check_command and will exit if occ_command fails + sudo -u www-data php ${NCPATH}/occ app:enable "$1" + chown -R www-data:www-data "$NC_APPS_PATH" +fi +} + +download_verify_nextcloud_stable() { +while [ -z "$NCVERSION" ] +do + print_text_in_color "$ICyan" "Fetching the latest Nextcloud version..." + NCVERSION=$(curl -s -m 900 $NCREPO/ | sed --silent 's/.*href="nextcloud-\([^"]\+\).zip.asc".*/\1/p' | sort --version-sort | tail -1) + STABLEVERSION="nextcloud-$NCVERSION" + print_text_in_color "$IGreen" "$NCVERSION" +done +install_if_not gnupg +rm -f "$HTML/$STABLEVERSION.tar.bz2" +cd $HTML +print_text_in_color "$ICyan" "Downloading $STABLEVERSION..." +curl -fSLO --retry 3 "$NCREPO/$STABLEVERSION.tar.bz2" +mkdir -p "$GPGDIR" +curl_to_dir "$NCREPO" "$STABLEVERSION.tar.bz2.asc" "$GPGDIR" +chmod -R 600 "$GPGDIR" +gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys "$OpenPGP_fingerprint" +gpg --verify "$GPGDIR/$STABLEVERSION.tar.bz2.asc" "$HTML/$STABLEVERSION.tar.bz2" +rm -r "$GPGDIR" +rm -f releases +} + +# Initial download of script in ../static +# call like: download_static_script name_of_script +download_static_script() { + # Get ${1} script + rm -f "${SCRIPTS}/${1}.sh" "${SCRIPTS}/${1}.php" "${SCRIPTS}/${1}.py" + if ! { curl_to_dir "${STATIC}" "${1}.sh" "$SCRIPTS" || curl_to_dir "${STATIC}" "${1}.php" "$SCRIPTS" || curl_to_dir "${STATIC}" "${1}.py" "$SCRIPTS"; } + then + print_text_in_color "$IRed" "{$1} failed to download. Please run: 'sudo curl -sLO ${STATIC}/${1}.sh|.php|.py' again." + print_text_in_color "$ICyan" "If you get this error when running the nextcloud-startup-script then just re-run it with:" + print_text_in_color "$ICyan" "'sudo bash $SCRIPTS/nextcloud-startup-script.sh' and all the scripts will be downloaded again" + exit 1 + fi +} + +# Initial download of script in ../lets-encrypt +# call like: download_le_script name_of_script +download_le_script() { + # Get ${1} script + rm -f "${SCRIPTS}/${1}.sh" "${SCRIPTS}/${1}.php" "${SCRIPTS}/${1}.py" + if ! { curl_to_dir "${LETS_ENC}" "${1}.sh" "$SCRIPTS" || curl_to_dir "${LETS_ENC}" "${1}.php" "$SCRIPTS" || curl_to_dir "${LETS_ENC}" "${1}.py" "$SCRIPTS"; } + then + print_text_in_color "$IRed" "{$1} failed to download. Please run: 'sudo curl -sLO ${STATIC}/${1}.sh|.php|.py' again." + print_text_in_color "$ICyan" "If you get this error when running the nextcloud-startup-script then just re-run it with:" + print_text_in_color "$ICyan" "'sudo bash $SCRIPTS/nextcloud-startup-script.sh' and all the scripts will be downloaded again" + exit 1 + fi +} + +# Run any script in ../master +# call like: run_main_script name_of_script +run_main_script() { + rm -f "${SCRIPTS}/${1}.sh" "${SCRIPTS}/${1}.php" "${SCRIPTS}/${1}.py" + if curl_to_dir "${GITHUB_REPO}" "${1}.sh" "$SCRIPTS" + then + bash "${SCRIPTS}/${1}.sh" + rm -f "${SCRIPTS}/${1}.sh" + elif curl_to_dir "${GITHUB_REPO}" "${1}.php" "$SCRIPTS" + then + php "${SCRIPTS}/${1}.php" + rm -f "${SCRIPTS}/${1}.php" + elif curl_to_dir "${GITHUB_REPO}" "${1}.py" "$SCRIPTS" + then + install_if_not python3 + python3 "${SCRIPTS}/${1}.py" + rm -f "${SCRIPTS}/${1}.py" + else + print_text_in_color "$IRed" "Downloading ${1} failed" + print_text_in_color "$ICyan" "Script failed to download. Please run: 'sudo curl -sLO ${GITHUB_REPO}/${1}.sh|php|py' again." + exit 1 + fi +} + +# Run any script in ../static +# call like: run_static_script name_of_script +run_static_script() { + # Get ${1} script + rm -f "${SCRIPTS}/${1}.sh" "${SCRIPTS}/${1}.php" "${SCRIPTS}/${1}.py" + if curl_to_dir "${STATIC}" "${1}.sh" "$SCRIPTS" + then + bash "${SCRIPTS}/${1}.sh" + rm -f "${SCRIPTS}/${1}.sh" + elif curl_to_dir "${STATIC}" "${1}.php" "$SCRIPTS" + then + php "${SCRIPTS}/${1}.php" + rm -f "${SCRIPTS}/${1}.php" + elif curl_to_dir "${STATIC}" "${1}.py" "$SCRIPTS" + then + install_if_not python3 + python3 "${SCRIPTS}/${1}.py" + rm -f "${SCRIPTS}/${1}.py" + else + print_text_in_color "$IRed" "Downloading ${1} failed" + print_text_in_color "$ICyan" "Script failed to download. Please run: 'sudo curl -sLO ${STATIC}/${1}.sh|php|py' again." + exit 1 + fi +} + +# Run any script in ../apps +# call like: run_app_script collabora|nextant|passman|spreedme|contacts|calendar|webmin|previewgenerator +run_app_script() { + rm -f "${SCRIPTS}/${1}.sh" "${SCRIPTS}/${1}.php" "${SCRIPTS}/${1}.py" + if curl_to_dir "${APP}" "${1}.sh" "$SCRIPTS" + then + bash "${SCRIPTS}/${1}.sh" + rm -f "${SCRIPTS}/${1}.sh" + elif curl_to_dir "${APP}" "${1}.php" "$SCRIPTS" + then + php "${SCRIPTS}/${1}.php" + rm -f "${SCRIPTS}/${1}.php" + elif curl_to_dir "${APP}" "${1}.py" "$SCRIPTS" + then + install_if_not python3 + python3 "${SCRIPTS}/${1}.py" + rm -f "${SCRIPTS}/${1}.py" + else + print_text_in_color "$IRed" "Downloading ${1} failed" + print_text_in_color "$ICyan" "Script failed to download. Please run: 'sudo curl -sLO ${APP}/${1}.sh|php|py' again." + exit + fi +} + +version(){ + local h t v + + [[ $2 = "$1" || $2 = "$3" ]] && return 0 + + v=$(printf '%s\n' "$@" | sort -V) + h=$(head -n1 <<<"$v") + t=$(tail -n1 <<<"$v") + + [[ $2 != "$h" && $2 != "$t" ]] +} + +version_gt() { + local v1 v2 IFS=. + read -ra v1 <<< "$1" + read -ra v2 <<< "$2" + printf -v v1 %03d "${v1[@]}" + printf -v v2 %03d "${v2[@]}" + [[ $v1 > $v2 ]] +} + +spinner_loading() { + pid=$! + spin='-\|/' + i=0 + while kill -0 $pid 2>/dev/null + do + i=$(( (i+1) %4 )) + printf "\r[${spin:$i:1}] " # Add text here, something like "Please be paitent..." maybe? + sleep .1 + done +} + +any_key() { + local PROMPT="$1" + read -r -sn 1 -p "$(printf "%b" "${IGreen}${PROMPT}${Color_Off}")";echo +} + +lowest_compatible_nc() { +if [ "${CURRENTVERSION%%.*}" -lt "$1" ] +then +msg_box "This script is developed to work with Nextcloud $1 and later. +This means we can't use our own script for now. But don't worry, +we automated the update process and we will now use Nextclouds updater instead. + +Press [OK] to continue the update, or press [CTRL+C] to abort. + +If you are using Nextcloud $1 and later and still see this message, +or experience other issues then please report this to $ISSUES" + + # Download the latest updater +# cd $NCPATH +# curl sLO https://github.com/nextcloud/updater/archive/master.zip +# install_if_not unzip +# unzip -q master.zip +# rm master.zip* +# rm updater/ -R +# mv updater-master/ updater/ +# download_static_script setup_secure_permissions_nextcloud -P $SCRIPTS +# bash $SECURE +# cd + + # Do the upgrade + chown -R www-data:www-data "$NCPATH" + rm -rf "$NCPATH"/assets + yes | sudo -u www-data php /var/www/nextcloud/updater/updater.phar + download_static_script setup_secure_permissions_nextcloud -P $SCRIPTS + bash $SECURE + occ_command maintenance:mode --off +fi + +# Check new version +# shellcheck source=lib.sh +NC_UPDATE=1 . <(curl -sL $GITHUB_REPO/lib.sh) +unset NC_UPDATE +if [ "${CURRENTVERSION%%.*}" -ge "$1" ] +then + sleep 1 +else +msg_box "It appears that something went wrong with the update. +Please report this to $ISSUES" +occ_command -V +exit +fi +} + +# Check universe reposiroty +check_universe() { +UNIV=$(apt-cache policy | grep http | awk '{print $3}' | grep universe | head -n 1 | cut -d "/" -f 2) +if [ "$UNIV" != "universe" ] +then + print_text_in_color "$ICyan" "Adding required repo (universe)." + add-apt-repository universe +fi +} + +# Check universe reposiroty +check_multiverse() { +MULTIV=$(apt-cache policy | grep http | awk '{print $3}' | grep multiverse | head -n 1 | cut -d "/" -f 2) +if [ "$MULTIV" != "multiverse" ] +then + print_text_in_color "$ICyan" "Adding required repo (multiverse)." + add-apt-repository multiverse +fi +} + +set_max_count() { +if grep -F 'vm.max_map_count=262144' /etc/sysctl.conf ; then + print_text_in_color "$ICyan" "Max map count already set, skipping..." +else + sysctl -w vm.max_map_count=262144 + { + echo "###################################################################" + echo "# Docker ES max virtual memory" + echo "vm.max_map_count=262144" + } >> /etc/sysctl.conf +fi +} + +# Check if docker is installed +is_docker_running() { + docker ps -a > /dev/null 2>&1 +} + +# Check if specific docker image is present +is_image_present() { + [[ $(docker images -q "$1") ]] +} + +# Check if old docker exists +# FULL NAME e.g. ark74/nc_fts or containrrr/watchtower or collabora/code +does_this_docker_exist() { +is_docker_running && is_image_present "$1"; +} + +install_docker() { +if ! is_docker_running +then + print_text_in_color "$ICyan" "Installing Docker CE..." + apt update -q4 & spinner_loading + install_if_not curl + curl -fsSL get.docker.com | sh +fi +# Set overlay2 +cat << OVERLAY2 > /etc/docker/daemon.json +{ + "storage-driver": "overlay2" +} +OVERLAY2 +systemctl daemon-reload +systemctl restart docker +} + +# Remove all dockers excluding one +# docker_prune_except_this fts_esror 'Full Text Search' +docker_prune_except_this() { +print_text_in_color "$ICyan" "Checking if there are any old images and removing them..." +DOCKERPS=$(docker ps -a | grep -v "$1" | awk 'NR>1 {print $1}') +if [ "$DOCKERPS" != "" ] +then +msg_box "Removing old Docker instance(s)... ($DOCKERPS) + +Please note that we will not remove $1 ($2). + +You will be given the option to abort when you hit OK." + any_key "Press any key to continue. Press CTRL+C to abort" + docker stop "$(docker ps -a | grep -v "$1" | awk 'NR>1 {print $1}')" + docker container prune -f + docker image prune -a -f + docker volume prune -f +fi +} + +# Remove selected Docker image +# docker_prune_this 'collabora/code' 'onlyoffice/documentserver' 'ark74/nc_fts' +docker_prune_this() { +if does_this_docker_exist "$1" +then +msg_box "Removing old Docker image: $1 +You will be given the option to abort when you hit OK." + any_key "Press any key to continue. Press CTRL+C to abort" + docker stop "$(docker container ls | grep "$1" | awk '{print $1}' | tail -1)" + docker container prune -f + docker image prune -a -f + docker volume prune -f +fi +} + +# countdown 'message looks like this' 10 +countdown() { +print_text_in_color "$ICyan" "$1" +secs="$(($2))" +while [ $secs -gt 0 ]; do + echo -ne "$secs\033[0K\r" + sleep 1 + : $((secs--)) +done +} + +print_text_in_color() { + printf "%b%s%b\n" "$1" "$2" "$Color_Off" +} + +# Apply patch +# git_apply_patch 15992 server 16.0.2 +# 1 = pull +# 2 = repository +# Nextcloud version +git_apply_patch() { +if [[ "$CURRENTVERSION" = "$3" ]] +then + curl_to_dir "https://patch-diff.githubusercontent.com/raw/nextcloud/${2}/pull" "${1}.patch" "/tmp" + install_if_not git + cd "$NCPATH" + if git apply --check /tmp/"${1}".patch >/dev/null 2>&1 + then + print_text_in_color "$IGreen" "Applying patch https://github.com/nextcloud/${2}/pull/${1} ..." + git apply /tmp/"${1}".patch + fi +fi +} + +# Check if it's the Home/SME Server + +#if home_sme_server +#then +# do something +#fi + +home_sme_server() { +if lshw -c system | grep -q NUC8i3BEH +then + if lshw -c memory | grep -q BLS16G4S240FSD.16FBD + then + if lshw -c disk | grep -q ST2000LM015-2E81 + then + NEXTCLOUDHOMESME=yes-this-is-the-home-sme-server + fi + fi +fi + +if [ -n "$NEXTCLOUDHOMESME" ] +then + return 0 +else + return 1 +fi +} + +## bash colors +# Reset +Color_Off='\e[0m' # Text Reset + +# Regular Colors +Black='\e[0;30m' # Black +Red='\e[0;31m' # Red +Green='\e[0;32m' # Green +Yellow='\e[0;33m' # Yellow +Blue='\e[0;34m' # Blue +Purple='\e[0;35m' # Purple +Cyan='\e[0;36m' # Cyan +White='\e[0;37m' # White + +# Bold +BBlack='\e[1;30m' # Black +BRed='\e[1;31m' # Red +BGreen='\e[1;32m' # Green +BYellow='\e[1;33m' # Yellow +BBlue='\e[1;34m' # Blue +BPurple='\e[1;35m' # Purple +BCyan='\e[1;36m' # Cyan +BWhite='\e[1;37m' # White + +# Underline +UBlack='\e[4;30m' # Black +URed='\e[4;31m' # Red +UGreen='\e[4;32m' # Green +UYellow='\e[4;33m' # Yellow +UBlue='\e[4;34m' # Blue +UPurple='\e[4;35m' # Purple +UCyan='\e[4;36m' # Cyan +UWhite='\e[4;37m' # White + +# Background +On_Black='\e[40m' # Black +On_Red='\e[41m' # Red +On_Green='\e[42m' # Green +On_Yellow='\e[43m' # Yellow +On_Blue='\e[44m' # Blue +On_Purple='\e[45m' # Purple +On_Cyan='\e[46m' # Cyan +On_White='\e[47m' # White + +# High Intensity +IBlack='\e[0;90m' # Black +IRed='\e[0;91m' # Red +IGreen='\e[0;92m' # Green +IYellow='\e[0;93m' # Yellow +IBlue='\e[0;94m' # Blue +IPurple='\e[0;95m' # Purple +ICyan='\e[0;96m' # Cyan +IWhite='\e[0;97m' # White + +# Bold High Intensity +BIBlack='\e[1;90m' # Black +BIRed='\e[1;91m' # Red +BIGreen='\e[1;92m' # Green +BIYellow='\e[1;93m' # Yellow +BIBlue='\e[1;94m' # Blue +BIPurple='\e[1;95m' # Purple +BICyan='\e[1;96m' # Cyan +BIWhite='\e[1;97m' # White + +# High Intensity backgrounds +On_IBlack='\e[0;100m' # Black +On_IRed='\e[0;101m' # Red +On_IGreen='\e[0;102m' # Green +On_IYellow='\e[0;103m' # Yellow +On_IBlue='\e[0;104m' # Blue +On_IPurple='\e[0;105m' # Purple +On_ICyan='\e[0;106m' # Cyan +On_IWhite='\e[0;107m' # White diff --git a/nextcloud-startup-script.sh b/nextcloud-startup-script.sh new file mode 100755 index 0000000..9378612 --- /dev/null +++ b/nextcloud-startup-script.sh @@ -0,0 +1,665 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +######### + +IRed='\e[0;91m' # Red +IGreen='\e[0;92m' # Green +ICyan='\e[0;96m' # Cyan +Color_Off='\e[0m' # Text Reset +print_text_in_color() { + printf "%b%s%b\n" "$1" "$2" "$Color_Off" +} + +print_text_in_color "$ICyan" "Fetching all the variables from lib.sh..." + +is_process_running() { +PROCESS="$1" + +while : +do + RESULT=$(pgrep "${PROCESS}") + + if [ "${RESULT:-null}" = null ]; then + break + else + print_text_in_color "$ICyan" "${PROCESS} is running, waiting for it to stop..." + sleep 10 + fi +done +} + +######### + +# Check if dpkg or apt is running +is_process_running apt +is_process_running dpkg + +# Use local lib file in case there is no internet connection +if [ -f /var/scripts/lib.sh ] +then +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +NCDB=1 && FIRST_IFACE=1 && CHECK_CURRENT_REPO=1 source /var/scripts/lib.sh +unset NCDB +unset FIRST_IFACE +unset CHECK_CURRENT_REPO + # If we have internet, then use the latest variables from the lib remote file +elif print_text_in_color "$ICyan" "Testing internet connection..." && ping github.com -c 2 +then +true +# shellcheck source=lib.sh +NCDB=1 && FIRST_IFACE=1 && CHECK_CURRENT_REPO=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset FIRST_IFACE +unset CHECK_CURRENT_REPO +unset NCDB +else + print_text_in_color "$IRed" "You don't seem to have a working internet connection, and /var/scripts/lib.sh is missing so you can't run this script." + print_text_in_color "$ICyan" "Please report this to https://github.com/nextcloud/vm/issues/" + exit 1 +fi + +# Check if root +root_check + +# Check network +if network_ok +then + print_text_in_color "$IGreen" "Online!" +else + print_text_in_color "$ICyan" "Setting correct interface..." + [ -z "$IFACE" ] && IFACE=$(lshw -c network | grep "logical name" | awk '{print $3; exit}') + # Set correct interface + cat <<-SETDHCP > "/etc/netplan/01-netcfg.yaml" +network: + version: 2 + renderer: networkd + ethernets: + $IFACE: + dhcp4: yes + dhcp6: yes +SETDHCP + check_command netplan apply + check_command service network-manager restart + ip link set "$IFACE" down + wait + ip link set "$IFACE" up + wait + check_command service network-manager restart + print_text_in_color "$ICyan" "Checking connection..." + sleep 1 + if ! nslookup github.com + then +msg_box "The script failed to get an address from DHCP. +You must have a working network connection to run this script. + +You will now be provided with the option to set a static IP manually instead." + + # Run static_ip script + bash /var/scripts/static_ip.sh + fi +fi + +# Check network again +if network_ok +then + print_text_in_color "$IGreen" "Online!" +else +msg_box "Network NOT OK. You must have a working network connection to run this script. + +Please contact us for support: +https://shop.hanssonit.se/product/premium-support-per-30-minutes/ + +Please also post this issue on: https://github.com/nextcloud/vm/issues" + exit 1 +fi + +# shellcheck source=lib.sh +NCDB=1 && CHECK_CURRENT_REPO=1 && NC_UPDATE=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset NC_UPDATE +unset CHECK_CURRENT_REPO +unset NCDB + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Nextcloud 16 is required. +lowest_compatible_nc 16 + +# Check that this run on the PostgreSQL VM +if ! is_this_installed postgresql-10 +then + print_text_in_color "$IRed" "This script is intended to be run on then PostgreSQL VM but PostgreSQL is not installed." + print_text_in_color "$IRed" "Aborting..." + exit 1 +fi + +# Set keyboard layout, important when changing passwords and such +if [ "$KEYBOARD_LAYOUT" = "se" ] +then + clear + print_text_in_color "$ICyan" "Current keyboard layout is Swedish." + if [[ "no" == $(ask_yes_or_no "Do you want to change keyboard layout?") ]] + then + print_text_in_color "$ICyan" "Not changing keyboard layout..." + sleep 1 + clear + else + dpkg-reconfigure keyboard-configuration + msg_box "We will now set the new keyboard layout directly in this session and reboot the server to apply the new keyboard settings.\n\nWhen the server are rebooted, please login as usual and run this script again." + setupcon --force && reboot + fi +fi + +# Set locales +print_text_in_color "$ICyan" "Setting locales..." +KEYBOARD_LAYOUT=$(localectl status | grep "Layout" | awk '{print $3}') +if [ "$KEYBOARD_LAYOUT" = "se" ] +then + print_text_in_color "$ICyan" "Svensk locale är redan konfigurerad." +elif [ "$KEYBOARD_LAYOUT" = "de" ] +then + sudo locale-gen "de_DE.UTF-8" && sudo dpkg-reconfigure --frontend=noninteractive locales +elif [ "$KEYBOARD_LAYOUT" = "us" ] +then + sudo locale-gen "en_US.UTF-8" && sudo dpkg-reconfigure --frontend=noninteractive locales +fi + +# Is this run as a pure root user? +if is_root +then + if [[ "$UNIXUSER" == "ncadmin" ]] + then + sleep 1 + else + if [ -z "$UNIXUSER" ] + then +msg_box "You seem to be running this as the pure root user. +You must run this as a regular user with sudo permissions. + +Please create a user with sudo permissions and the run this command: +sudo -u [user-with-sudo-permissions] sudo bash /var/scripts/nextcloud-startup-script.sh + +We will do this for you when you hit OK." + download_static_script adduser + bash $SCRIPTS/adduser.sh "$SCRIPTS/nextcloud-startup-script.sh" + rm $SCRIPTS/adduser.sh + else +msg_box "You probably see this message if the user 'ncadmin' does not exist on the system, +which could be the case if you are running directly from the scripts on Gihub and not the VM. + +As long as the user you created have sudo permissions it's safe to continue. +This would be the case if you created a new user with the script in the previous step. + +If the user you are running this script with is a user that doesn't have sudo permissions, +please abort this script and report this issue to $ISSUES." + fi + fi +fi + +######## The first setup is OK to run to this point several times, but not any further ######## +if [ -f "$SCRIPTS/you-can-not-run-the-startup-script-several-times" ] +then +msg_box "The Nextcloud startup script that handles the first setup (this one) is desinged to be run once, not several times in a row. + +If you feel uncertain about adding some extra features during this setup, then it's best to wait until after the first setup is done. You can always add all the extra features later. + +[For the Nextcloud VM:] +Please delete this VM from your host and reimport it once again, then run this setup like you did the first time. + +[For the Nextcloud Home/SME Server:] +It's a bit more tricky since you can't revert in the same way as with a VM. The best thing you can do now is to save all the output from the session you ran before this one + write down all the steps you took and send and email to: +github@hanssonit.se with the subject 'Issues with first setup', and we'll take it from there. + +Full documentation can be found here: https://docs.hanssonit.se +Please report any bugs you find here: $ISSUES" + exit 1 +fi + +touch "$SCRIPTS/you-can-not-run-the-startup-script-several-times" + +echo +print_text_in_color "$ICyan" "Getting scripts from GitHub to be able to run the first setup..." +# Scripts in static (.sh, .php, .py) +download_static_script temporary-fix +download_static_script update +download_static_script trusted +download_static_script test_connection +download_static_script setup_secure_permissions_nextcloud +download_static_script change_db_pass +download_static_script nextcloud +download_static_script update-config +download_le_script activate-ssl +if home_sme_server +then + download_static_script nhss_index + mv $SCRIPTS/nhss_index.php $HTML/index.php && rm -f $HTML/html/index.html + chmod 750 $HTML/index.php && chown www-data:www-data $HTML/index.php +else + download_static_script index + mv $SCRIPTS/index.php $HTML/index.php && rm -f $HTML/html/index.html + chmod 750 $HTML/index.php && chown www-data:www-data $HTML/index.php +fi + +# Change 000-default to $WEB_ROOT +sed -i "s|DocumentRoot /var/www/html|DocumentRoot $HTML|g" /etc/apache2/sites-available/000-default.conf + +# Make possible to see the welcome screen (without this php-fpm won't reach it) + sed -i '14i\ # http://lost.l-w.ca/0x05/apache-mod_proxy_fcgi-and-php-fpm/' /etc/apache2/sites-available/000-default.conf + sed -i '15i\ ' /etc/apache2/sites-available/000-default.conf + sed -i '16i\ ' /etc/apache2/sites-available/000-default.conf + sed -i '17i\ SetHandler "proxy:unix:/run/php/php'$PHPVER'-fpm.nextcloud.sock|fcgi://localhost"' /etc/apache2/sites-available/000-default.conf + sed -i '18i\ ' /etc/apache2/sites-available/000-default.conf + sed -i '19i\ ' /etc/apache2/sites-available/000-default.conf + sed -i '20i\ ' /etc/apache2/sites-available/000-default.conf + +# Make $SCRIPTS excutable +chmod +x -R $SCRIPTS +chown root:root -R $SCRIPTS + +# Allow $UNIXUSER to run figlet script +chown "$UNIXUSER":"$UNIXUSER" "$SCRIPTS/nextcloud.sh" + +msg_box "This script will configure your Nextcloud and activate SSL. +It will also do the following: + +- Generate new SSH keys for the server +- Generate new PostgreSQL password +- Install selected apps and automatically configure them +- Detect and set hostname +- Detect and set trusted domains +- Detect the best Ubuntu mirrors depending on your location +- Upgrade your system and Nextcloud to latest version +- Set secure permissions to Nextcloud +- Set new passwords to Linux and Nextcloud +- Change timezone +- Set correct Rewriterules for Nextcloud +- Copy content from .htaccess to .user.ini (because we use php-fpm) +- Add additional options if you choose them +- And more..." + +msg_box "Please note: + +[#] The script will take about 10 minutes to finish, depending on your internet connection. + +[#] Please read the on-screen instructions carefully, they will guide you through the setup. + +[#] When complete it will delete all the *.sh, *.html, *.tar, *.zip inside: + /root + /home/$UNIXUSER + +[#] Please consider donating if you like the product: + https://shop.hanssonit.se/product-category/donate/ + +[#] You can also ask for help here: + https://help.nextcloud.com/c/support/appliances-docker-snappy-vm + https://shop.hanssonit.se/product/premium-support-per-30-minutes/" +clear + +# Change Timezone +print_text_in_color "$ICyan" "Current timezone is $(cat /etc/timezone)" +if [[ "no" == $(ask_yes_or_no "Do you want to change the timezone?") ]] +then + print_text_in_color "$ICyan" "Not changing timezone..." + sleep 1 + clear +else + dpkg-reconfigure tzdata +fi + +# Change timezone in PHP +sed -i "s|;date.timezone.*|date.timezone = $(cat /etc/timezone)|g" "$PHP_INI" + +# Change timezone for logging +occ_command config:system:set logtimezone --value="$(cat /etc/timezone)" +clear + +# Check where the best mirrors are and update +msg_box "To make downloads as fast as possible when updating you should have mirrors that are as close to you as possible. +This VM comes with mirrors based on servers in that where used when the VM was released and packaged. + +If you are located outside of Europe, we recomend you to change the mirrors so that downloads are faster." +print_text_in_color "$ICyan" "Checking current mirror..." +print_text_in_color "$ICyan" "Your current server repository is: $REPO" + +if [[ "no" == $(ask_yes_or_no "Do you want to try to find a better mirror?") ]] +then + print_text_in_color "$ICyan" "Keeping $REPO as mirror..." + sleep 1 +else + print_text_in_color "$ICyan" "Locating the best mirrors..." + apt update -q4 & spinner_loading + apt install python-pip -y + pip install \ + --upgrade pip \ + apt-select + check_command apt-select -m up-to-date -t 5 -c -C "$(localectl status | grep "Layout" | awk '{print $3}')" + sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup && \ + if [ -f sources.list ] + then + sudo mv sources.list /etc/apt/ + fi +fi +clear + +# Pretty URLs +print_text_in_color "$ICyan" "Setting RewriteBase to \"/\" in config.php..." +chown -R www-data:www-data $NCPATH +occ_command config:system:set overwrite.cli.url --value="http://localhost/" +occ_command config:system:set htaccess.RewriteBase --value="/" +occ_command maintenance:update:htaccess +bash $SECURE & spinner_loading + +# Generate new SSH Keys +printf "\nGenerating new SSH keys for the server...\n" +rm -v /etc/ssh/ssh_host_* +dpkg-reconfigure openssh-server + +# Generate new PostgreSQL password +print_text_in_color "$ICyan" "Generating new PostgreSQL password..." +check_command bash "$SCRIPTS/change_db_pass.sh" +sleep 3 +clear + +msg_box "The following script will install a trusted +SSL certificate through Let's Encrypt. + +It's recommended to use SSL together with Nextcloud. +Please open port 80 and 443 to this servers IP before you continue. + +More information can be found here: +https://www.techandme.se/open-port-80-443/" + +# Extra configurations +whiptail --title "Extra configurations" --checklist --separate-output "Choose what you want to configure\nSelect by pressing the spacebar" "$WT_HEIGHT" "$WT_WIDTH" 4 \ +"Security" "(Add extra security based on this http://goo.gl/gEJHi7)" OFF \ +"Static IP" "(Set static IP in Ubuntu with netplan.io)" OFF \ +"Automatic updates" "(Automatically update your server every week on Sundays)" OFF 2>results + +while read -r -u 9 choice +do + case $choice in + "Security") + clear + run_static_script security + ;; + + "Static IP") + clear + run_static_script static_ip + rm -f "$SCRIPTS"/lib.sh + ;; + + "Automatic updates") + clear + run_static_script automatic_updates + ;; + + *) + ;; + esac +done 9< results +rm -f results + +# Let's Encrypt +if [[ "yes" == $(ask_yes_or_no "Do you want to install SSL?") ]] +then + bash $SCRIPTS/activate-ssl.sh +else + echo + print_text_in_color "$ICyan" "OK, but if you want to run it later, just type: sudo bash $SCRIPTS/activate-ssl.sh" + any_key "Press any key to continue..." +fi +clear + +# Install Apps +whiptail --title "Which apps do you want to install?" --checklist --separate-output "Automatically configure and install selected apps\nSelect by pressing the spacebar" "$WT_HEIGHT" "$WT_WIDTH" 4 \ +"Fail2ban" "(Extra Bruteforce protection) " OFF \ +"Adminer" "(PostgreSQL GUI) " OFF \ +"Netdata" "(Real-time server monitoring) " OFF \ +"Collabora" "(Online editing [2GB RAM]) " OFF \ +"OnlyOffice" "(Online editing [2GB RAM]) " OFF \ +"Bitwarden" "(External password manager) " OFF \ +"FullTextSearch" "(Elasticsearch for Nextcloud [2GB RAM]) " OFF \ +"PreviewGenerator" "(Pre-generate previews) " OFF \ +"LDAP" "(Windows Active directory) " OFF \ +"Talk" "(Nextcloud Video calls and chat) " OFF 2>results + +while read -r -u 9 choice +do + case $choice in + Fail2ban) + clear + run_app_script fail2ban + ;; + + Adminer) + clear + run_app_script adminer + ;; + + Netdata) + clear + run_app_script netdata + ;; + + OnlyOffice) + clear + run_app_script onlyoffice + ;; + + Collabora) + clear + run_app_script collabora + ;; + + Bitwarden) + clear + run_app_script tmbitwarden + ;; + + FullTextSearch) + clear + run_app_script fulltextsearch + ;; + + PreviewGenerator) + clear + run_app_script previewgenerator + ;; + + LDAP) + clear + print_text_in_color "$ICyan" "Installing LDAP..." + if install_and_enable_app user_ldap + then + msg_box "LDAP installed! Please visit https://subdomain.yourdomain.com/settings/admin/ldap to finish the setup once this script is done." + else msg_box "LDAP installation failed." + fi + ;; + + Talk) + clear + run_app_script talk + ;; + + *) + ;; + esac +done 9< results +rm -f results +clear + +# Change passwords +# CLI USER +print_text_in_color "$ICyan" "For better security, change the system user password for [$(getent group sudo | cut -d: -f4 | cut -d, -f1)]" +any_key "Press any key to change password for system user..." +while true +do + sudo passwd "$(getent group sudo | cut -d: -f4 | cut -d, -f1)" && break +done +echo +clear +# NEXTCLOUD USER +NCADMIN=$(occ_command user:list | awk '{print $3}') +print_text_in_color "$ICyan" "The current admin user in Nextcloud GUI is [$NCADMIN]" +print_text_in_color "$ICyan" "We will now replace this user with your own." +any_key "Press any key to replace the current admin user for Nextcloud..." +# Create new user +while true +do + print_text_in_color "$ICyan" "Please enter the username for your new user:" + read -r NEWUSER + sudo -u www-data $NCPATH/occ user:add "$NEWUSER" -g admin && break +done +# Delete old user +if [[ "$NCADMIN" ]] +then + print_text_in_color "$ICyan" "Deleting $NCADMIN..." + occ_command user:delete "$NCADMIN" +fi +clear + +# Set notifications for admin +NCADMIN=$(occ_command user:list | awk '{print $3}') +occ_command notification:generate -l "Please remember to setup SMTP to be able to send shared links, user notifications and more via email. Please go here and start setting it up: https://your-nextcloud/settings/admin." "$NCADMIN" "Please setup SMTP" +occ_command notification:generate -l "If you need support, please visit the shop: https://shop.hanssonit.se" "$NCADMIN" "Do you need support?" + +# Fixes https://github.com/nextcloud/vm/issues/58 +a2dismod status +restart_webserver + +if home_sme_server +then + # Add specific values to PHP-FPM based on 16 GB RAM + check_command sed -i "s|pm.max_children.*|pm.max_children = 307|g" "$PHP_POOL_DIR"/nextcloud.conf + check_command sed -i "s|pm.start_servers.*|pm.start_servers = 30|g" "$PHP_POOL_DIR"/nextcloud.conf + check_command sed -i "s|pm.min_spare_servers.*|pm.min_spare_servers = 20|g" "$PHP_POOL_DIR"/nextcloud.conf + check_command sed -i "s|pm.max_spare_servers.*|pm.max_spare_servers = 257|g" "$PHP_POOL_DIR"/nextcloud.conf + restart_webserver +else + # Calculate the values of PHP-FPM based on the amount of RAM available (minimum 2 GB or 8 children) + calculate_php_fpm + + # Run again if values are reset on last run + calculate_php_fpm +fi + +# Add temporary fix if needed +bash "$SCRIPTS"/temporary-fix.sh +rm "$SCRIPTS"/temporary-fix.sh + +# Cleanup 1 +occ_command maintenance:repair +rm -f "$SCRIPTS/ip.sh" +rm -f "$SCRIPTS/change_db_pass.sh" +rm -f "$SCRIPTS/test_connection.sh" +rm -f "$SCRIPTS/instruction.sh" +rm -f "$NCDATA/nextcloud.log" +rm -f "$SCRIPTS/static_ip.sh" + +find /root "/home/$UNIXUSER" -type f \( -name '*.sh*' -o -name '*.html*' -o -name '*.tar*' -o -name 'results' -o -name '*.zip*' \) -delete +find "$NCPATH" -type f \( -name 'results' -o -name '*.sh*' \) -delete +sed -i "s|instruction.sh|nextcloud.sh|g" "/home/$UNIXUSER/.bash_profile" + +truncate -s 0 \ + /root/.bash_history \ + "/home/$UNIXUSER/.bash_history" \ + /var/spool/mail/root \ + "/var/spool/mail/$UNIXUSER" \ + /var/log/apache2/access.log \ + /var/log/apache2/error.log \ + /var/log/cronjobs_success.log \ + "$VMLOGS/nextcloud.log" + +sed -i "s|sudo -i||g" "/home/$UNIXUSER/.bash_profile" + +cat << ROOTNEWPROFILE > "/root/.bash_profile" +# ~/.profile: executed by Bourne-compatible login shells. + +if [ "/bin/bash" ] +then + if [ -f ~/.bashrc ] + then + . ~/.bashrc + fi +fi + +if [ -x /var/scripts/nextcloud-startup-script.sh ] +then + /var/scripts/nextcloud-startup-script.sh +fi + +if [ -x /var/scripts/history.sh ] +then + /var/scripts/history.sh +fi + +mesg n + +ROOTNEWPROFILE + +# Download all app scripts +print_text_in_color "$ICyan" "Downloading all the latest app scripts to $SCRIPTS/apps..." +mkdir -p $SCRIPTS/apps +cd $SCRIPTS/apps +check_command curl -s https://codeload.github.com/nextcloud/vm/tar.gz/master | tar -xz --strip=2 vm-master/apps + +# Upgrade system +print_text_in_color "$ICyan" "System will now upgrade..." +bash $SCRIPTS/update.sh + +# Cleanup 2 +apt autoremove -y +apt autoclean + +# Set trusted domain in config.php +if [ -f "$SCRIPTS"/trusted.sh ] +then + bash "$SCRIPTS"/trusted.sh + rm -f "$SCRIPTS"/trusted.sh +else + run_static_script trusted +fi + +# Success! +msg_box "Congratulations! You have successfully installed Nextcloud! + +Login to Nextcloud in your browser: +- IP: $ADDRESS +- Hostname: $(hostname -f) + +SUPPORT: +Please ask for help in the forums, visit our shop to buy support, +or buy a yearly subscription from Nextcloud: +- SUPPORT: https://shop.hanssonit.se/product/premium-support-per-30-minutes/ +- FORUM: https://help.nextcloud.com/ +- SUBSCRIPTION: https://nextcloud.com/pricing/ (Please refer to @enoch85) + +Please report any bugs here: https://github.com/nextcloud/vm/issues + +TIPS & TRICKS: +1. Publish your server online: https://goo.gl/iUGE2U + +2. To login to PostgreSQL just type: sudo -u postgres psql nextcloud_db + +3. To update this VM just type: sudo bash /var/scripts/update.sh + +4. Change IP to something outside DHCP: sudo nano /etc/netplan/01-netcfg.yaml + +5. For a better experience it's a good idea to setup an email account here: + https://yourcloud.xyz/settings/admin" + +# Prefer IPv6 +sed -i "s|precedence ::ffff:0:0/96 100|#precedence ::ffff:0:0/96 100|g" /etc/gai.conf + +# Reboot +print_text_in_color "$IGreen" "Installation done, system will now reboot..." +rm -f "$SCRIPTS/you-can-not-run-the-startup-script-several-times" +rm -f "$SCRIPTS/nextcloud-startup-script.sh" +reboot diff --git a/nextcloud_install_production.sh b/nextcloud_install_production.sh new file mode 100755 index 0000000..2ea9715 --- /dev/null +++ b/nextcloud_install_production.sh @@ -0,0 +1,766 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# Prefer IPv4 +sed -i "s|#precedence ::ffff:0:0/96 100|precedence ::ffff:0:0/96 100|g" /etc/gai.conf + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check if dpkg or apt is running +is_process_running apt +is_process_running dpkg + +# Install curl if not existing +if [ "$(dpkg-query -W -f='${Status}' "curl" 2>/dev/null | grep -c "ok installed")" == "1" ] +then + print_text_in_color "$IGreen" "curl OK" +else + apt update -q4 & spinner_loading + apt install curl -y +fi + +# Install lshw if not existing +if [ "$(dpkg-query -W -f='${Status}' "lshw" 2>/dev/null | grep -c "ok installed")" == "1" ] +then + print_text_in_color "$IGreen" "lshw OK" +else + apt update -q4 & spinner_loading + apt install lshw -y +fi + +# Install net-tools if not existing +if [ "$(dpkg-query -W -f='${Status}' "net-tools" 2>/dev/null | grep -c "ok installed")" == "1" ] +then + print_text_in_color "$IGreen" "net-tools OK" +else + apt update -q4 & spinner_loading + apt install net-tools -y +fi + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +FIRST_IFACE=1 && CHECK_CURRENT_REPO=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset FIRST_IFACE +unset CHECK_CURRENT_REPO + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +# Set keyboard layout +if [ "$KEYBOARD_LAYOUT" != "se" ] +then + print_text_in_color "$ICyan" "Current keyboard layout is $KEYBOARD_LAYOUT" + if [[ "no" == $(ask_yes_or_no "Do you want to change keyboard layout?") ]] + then + print_text_in_color "$ICyan" "Not changing keyboard layout..." + sleep 1 + else + dpkg-reconfigure keyboard-configuration + msg_box "The server will now be rebooted to apply the new keyboard settings. Please run this script again once rebooted." + reboot + fi +fi + +# Set locales +KEYBOARD_LAYOUT=$(localectl status | grep "Layout" | awk '{print $3}') +install_if_not language-pack-en-base +if [ "$KEYBOARD_LAYOUT" = "se" ] +then + sudo locale-gen "sv_SE.UTF-8" && sudo dpkg-reconfigure --frontend=noninteractive locales +elif [ "$KEYBOARD_LAYOUT" = "de" ] +then + sudo locale-gen "de_DE.UTF-8" && sudo dpkg-reconfigure --frontend=noninteractive locales +else + sudo locale-gen "en_US.UTF-8" && sudo dpkg-reconfigure --frontend=noninteractive locales +fi + +# Test RAM size (2GB min) + CPUs (min 1) +ram_check 2 Nextcloud +cpu_check 1 Nextcloud + +# Create new current user +download_static_script adduser +bash $SCRIPTS/adduser.sh "nextcloud_install_production.sh" +rm -f $SCRIPTS/adduser.sh + +# Check distribution and version +check_distro_version +check_universe +check_multiverse + +# Check if key is available +if ! site_200 "$NCREPO" +then +msg_box "Nextcloud repo is not available, exiting..." + exit 1 +fi + +# Check if it's a clean server +stop_if_installed postgresql +stop_if_installed apache2 +stop_if_installed php +stop_if_installed php-fpm +stop_if_installed php"$PHPVER"-fpm +stop_if_installed php7.0-fpm +stop_if_installed php7.1-fpm +stop_if_installed php7.3-fpm +stop_if_installed mysql-common +stop_if_installed mariadb-server + +# Create $SCRIPTS dir +if [ ! -d "$SCRIPTS" ] +then + mkdir -p "$SCRIPTS" +fi + +# Create $VMLOGS dir +if [ ! -d "$VMLOGS" ] +then + mkdir -p "$VMLOGS" +fi + +# Install needed network +install_if_not netplan.io +install_if_not network-manager + +# Install build-essentials to get make +install_if_not build-essential + +# Set dual or single drive setup +msg_box "This VM is designed to run with two disks, one for OS and one for DATA. This will get you the best performance since the second disk is using ZFS which is a superior filesystem. +You could still choose to only run on one disk though, which is not recommended, but maybe your only option depending on which hypervisor you are running. + +You will now get the option to decide which disk you want to use for DATA, or run the automatic script that will choose the available disk automatically." + +whiptail --title "Choose disk format" --radiolist --separate-output "How would you like to configure your disks?\nSelect by pressing the spacebar and ENTER" "$WT_HEIGHT" "$WT_WIDTH" 4 \ +"2 Disks Auto" "(Automatically configured) " on \ +"2 Disks Auto NUC Server" "(Nextcloud Home/SME Server, /dev/sda) " off \ +"2 Disks Manual" "(Choose by yourself) " off \ +"1 Disk" "(Only use one disk /mnt/ncdata - NO ZFS!) " off 2>results + +choice=$(< results) + case "$choice" in + "2 Disks Auto") + run_static_script format-sdb + ;; + "2 Disks Auto NUC Server") + run_static_script format-sda-nuc-server + ;; + "2 Disks Manual") + run_static_script format-chosen + ;; + "1 Disk") + print_text_in_color "$IRed" "1 Disk setup chosen." + sleep 2 + ;; + *) + ;; + esac + +# Set DNS resolver +whiptail --title "Set DNS Resolver" --radiolist --separate-output "Which DNS provider should this Nextcloud box use?\nSelect by pressing the spacebar and ENTER" "$WT_HEIGHT" "$WT_WIDTH" 4 \ +"Quad9" "(https://www.quad9.net/) " on \ +"Cloudflare" "(https://www.cloudflare.com/dns/) " off \ +"Local" "($GATEWAY + 149.112.112.112) " off 2>results + +choice=$(< results) + case "$choice" in + Quad9) + sed -i "s|#DNS=.*|DNS=9.9.9.9 2620:fe::fe|g" /etc/systemd/resolved.conf + sed -i "s|#FallbackDNS=.*|FallbackDNS=149.112.112.112 2620:fe::9|g" /etc/systemd/resolved.conf + ;; + Cloudflare) + sed -i "s|#DNS=.*|DNS=1.1.1.1 2606:4700:4700::1111|g" /etc/systemd/resolved.conf + sed -i "s|#FallbackDNS=.*|FallbackDNS=1.0.0.1 2606:4700:4700::1001|g" /etc/systemd/resolved.conf + ;; + Local) + sed -i "s|#DNS=.*|DNS=$GATEWAY|g" /etc/systemd/resolved.conf + sed -i "s|#FallbackDNS=.*|FallbackDNS=149.112.112.112 2620:fe::9|g" /etc/systemd/resolved.conf + ;; + *) + ;; + esac +check_command systemctl restart network-manager.service +network_ok + +# Check where the best mirrors are and update +echo +printf "Your current server repository is: ${ICyan}%s${Color_Off}\n" "$REPO" +if [[ "no" == $(ask_yes_or_no "Do you want to try to find a better mirror?") ]] +then + print_text_in_color "$ICyan" "Keeping $REPO as mirror..." + sleep 1 +else + print_text_in_color "$ICyan" "Locating the best mirrors..." + apt update -q4 & spinner_loading + apt install python-pip -y + pip install \ + --upgrade pip \ + apt-select + apt-select -m up-to-date -t 5 -c + sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup && \ + if [ -f sources.list ] + then + sudo mv sources.list /etc/apt/ + fi +fi + +# Install PostgreSQL +# sudo add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" +# curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - +apt update -q4 & spinner_loading +apt install postgresql-10 -y + +# Create DB +cd /tmp +sudo -u postgres psql <> /etc/apache2/apache2.conf + + check_command systemctl restart apache2.service +fi + +# Install PHP "$PHPVER" +apt update -q4 & spinner_loading +check_command apt install -y \ + php"$PHPVER"-fpm \ + php"$PHPVER"-intl \ + php"$PHPVER"-ldap \ + php"$PHPVER"-imap \ + php"$PHPVER"-gd \ + php"$PHPVER"-pgsql \ + php"$PHPVER"-curl \ + php"$PHPVER"-xml \ + php"$PHPVER"-zip \ + php"$PHPVER"-mbstring \ + php"$PHPVER"-soap \ + php"$PHPVER"-smbclient \ + php"$PHPVER"-json \ + php"$PHPVER"-gmp \ + php"$PHPVER"-bz2 \ + php-pear + # php"$PHPVER"-imagick \ + # libmagickcore-6.q16-3-extra + +# Enable php-fpm +a2enconf php"$PHPVER"-fpm + +# Enable HTTP/2 server wide +print_text_in_color "$ICyan" "Enabling HTTP/2 server wide..." +cat << HTTP2_ENABLE > "$HTTP2_CONF" + + Protocols h2 h2c http/1.1 + H2Direct on + +HTTP2_ENABLE +print_text_in_color "$IGreen" "$HTTP2_CONF was successfully created" +a2enmod http2 +restart_webserver + +# Set up a php-fpm pool with a unixsocket +cat << POOL_CONF > "$PHP_POOL_DIR"/nextcloud.conf +[Nextcloud] +user = www-data +group = www-data +listen = /run/php/php"$PHPVER"-fpm.nextcloud.sock +listen.owner = www-data +listen.group = www-data +pm = dynamic +; max_children is set dynamically with calculate_php_fpm() +pm.max_children = 8 +pm.start_servers = 3 +pm.min_spare_servers = 2 +pm.max_spare_servers = 3 +env[HOSTNAME] = $(hostname -f) +env[PATH] = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin +env[TMP] = /tmp +env[TMPDIR] = /tmp +env[TEMP] = /tmp +security.limit_extensions = .php +php_admin_value [cgi.fix_pathinfo] = 1 + +; Optional +; pm.max_requests = 2000 +POOL_CONF + +# Disable the idling example pool. +mv "$PHP_POOL_DIR"/www.conf "$PHP_POOL_DIR"/www.conf.backup + +# Enable the new php-fpm config +restart_webserver + +# Calculate the values of PHP-FPM based on the amount of RAM available (it's done in the startup script as well) +calculate_php_fpm + +# Enable SMB client # already loaded with php-smbclient +# echo '# This enables php-smbclient' >> /etc/php/"$PHPVER"/apache2/php.ini +# echo 'extension="smbclient.so"' >> /etc/php/"$PHPVER"/apache2/php.ini + +# Install VM-tools +install_if_not open-vm-tools + +# Download and validate Nextcloud package +check_command download_verify_nextcloud_stable + +if [ ! -f "$HTML/$STABLEVERSION.tar.bz2" ] +then +msg_box "Aborting,something went wrong with the download of $STABLEVERSION.tar.bz2" + exit 1 +fi + +# Extract package +tar -xjf "$HTML/$STABLEVERSION.tar.bz2" -C "$HTML" & spinner_loading +rm "$HTML/$STABLEVERSION.tar.bz2" + +# Secure permissions +download_static_script setup_secure_permissions_nextcloud +bash $SECURE & spinner_loading + +# Install Nextcloud +print_text_in_color "$ICyan" "Installing Nextcloud..." +cd "$NCPATH" +occ_command maintenance:install \ +--data-dir="$NCDATA" \ +--database=pgsql \ +--database-name=nextcloud_db \ +--database-user="$NCUSER" \ +--database-pass="$PGDB_PASS" \ +--admin-user="$NCUSER" \ +--admin-pass="$NCPASS" +echo +print_text_in_color "$ICyan" "Nextcloud version:" +occ_command status +sleep 3 +echo + +# Prepare cron.php to be run every 15 minutes +crontab -u www-data -l | { cat; echo "*/5 * * * * php -f $NCPATH/cron.php > /dev/null 2>&1"; } | crontab -u www-data - + +# Change values in php.ini (increase max file size) +# max_execution_time +sed -i "s|max_execution_time =.*|max_execution_time = 3500|g" "$PHP_INI" +# max_input_time +sed -i "s|max_input_time =.*|max_input_time = 3600|g" "$PHP_INI" +# memory_limit +sed -i "s|memory_limit =.*|memory_limit = 512M|g" "$PHP_INI" +# post_max +sed -i "s|post_max_size =.*|post_max_size = 1100M|g" "$PHP_INI" +# upload_max +sed -i "s|upload_max_filesize =.*|upload_max_filesize = 1000M|g" "$PHP_INI" + +# Set loggging +occ_command config:system:set log_type --value=file +occ_command config:system:set logfile --value="$VMLOGS/nextcloud.log" +rm -f "$NCDATA/nextcloud.log" +occ_command config:system:set loglevel --value=2 +occ_command config:app:set admin_audit logfile --value="$VMLOGS/audit.log" +install_and_enable_app admin_audit + +# Set SMTP mail +occ_command config:system:set mail_smtpmode --value="smtp" + +# Forget login/session after 30 minutes +occ_command config:system:set remember_login_cookie_lifetime --value="1800" + +# Set logrotate (max 10 MB) +occ_command config:system:set log_rotate_size --value="10485760" + +# Set trashbin retention obligation (save it in trahbin for 6 months or delete when space is needed) +occ_command config:system:set trashbin_retention_obligation --value="auto, 180" + +# Set versions retention obligation (save versions for 12 months or delete when space is needed) +occ_command config:system:set versions_retention_obligation --value="auto, 365" + +# Remove simple signup +occ_command config:system:set simpleSignUpLink.shown --value="false" + +# Enable OPCache for PHP +# https://docs.nextcloud.com/server/14/admin_manual/configuration_server/server_tuning.html#enable-php-opcache +phpenmod opcache +{ +echo "# OPcache settings for Nextcloud" +echo "opcache.enable=1" +echo "opcache.enable_cli=1" +echo "opcache.interned_strings_buffer=8" +echo "opcache.max_accelerated_files=10000" +echo "opcache.memory_consumption=256" +echo "opcache.save_comments=1" +echo "opcache.revalidate_freq=1" +echo "opcache.validate_timestamps=1" +} >> "$PHP_INI" + +# PHP-FPM optimization +# https://geekflare.com/php-fpm-optimization/ +sed -i "s|;emergency_restart_threshold.*|emergency_restart_threshold = 10|g" /etc/php/"$PHPVER"/fpm/php-fpm.conf +sed -i "s|;emergency_restart_interval.*|emergency_restart_interval = 1m|g" /etc/php/"$PHPVER"/fpm/php-fpm.conf +sed -i "s|;process_control_timeout.*|process_control_timeout = 10|g" /etc/php/"$PHPVER"/fpm/php-fpm.conf + +# PostgreSQL values for PHP (https://docs.nextcloud.com/server/latest/admin_manual/configuration_database/linux_database_configuration.html#postgresql-database) +{ +echo "" +echo "[PostgresSQL]" +echo "pgsql.allow_persistent = On" +echo "pgsql.auto_reset_persistent = Off" +echo "pgsql.max_persistent = -1" +echo "pgsql.max_links = -1" +echo "pgsql.ignore_notice = 0" +echo "pgsql.log_notice = 0" +} >> "$PHP_FPM_DIR"/conf.d/20-pdo_pgsql.ini + +# Install Redis (distrubuted cache) +run_static_script redis-server-ubuntu + +# Enable igbinary for PHP +# https://github.com/igbinary/igbinary +if is_this_installed "php$PHPVER"-dev +then + if ! yes no | pecl install -Z igbinary + then + msg_box "igbinary PHP module installation failed" + exit + else + print_text_in_color "$IGreen" "igbinary PHP module installation OK!" + fi +{ +echo "# igbinary for PHP" +echo "extension=igbinary.so" +echo "session.serialize_handler=igbinary" +echo "igbinary.compact_strings=On" +} >> "$PHP_INI" +restart_webserver +fi + +# APCu (local cache) +if is_this_installed "php$PHPVER"-dev +then + if ! yes no | pecl install -Z apcu + then + msg_box "APCu PHP module installation failed" + exit + else + print_text_in_color "$IGreen" "APCu PHP module installation OK!" + fi +{ +echo "# APCu settings for Nextcloud" +echo "extension=apcu.so" +echo "apc.enabled=1" +echo "apc.max_file_size=5M" +echo "apc.shm_segments=1" +echo "apc.shm_size=128M" +echo "apc.entries_hint=4096" +echo "apc.ttl=3600" +echo "apc.gc_ttl=7200" +echo "apc.mmap_file_mask=NULL" +echo "apc.slam_defense=1" +echo "apc.enable_cli=1" +echo "apc.use_request_time=1" +echo "apc.serializer=igbinary" +echo "apc.coredump_unmap=0" +echo "apc.preload_path" +} >> "$PHP_INI" +restart_webserver +fi + +# Fix https://github.com/nextcloud/vm/issues/714 +print_text_in_color "$ICyan" "Optimizing Nextcloud..." +yes | occ_command db:convert-filecache-bigint +occ_command db:add-missing-indices + +# Install Figlet +install_if_not figlet + +# To be able to use snakeoil certs +install_if_not ssl-cert + +# Generate $HTTP_CONF +if [ ! -f $HTTP_CONF ] +then + touch "$HTTP_CONF" + cat << HTTP_CREATE > "$HTTP_CONF" + + +### YOUR SERVER ADDRESS ### +# ServerAdmin admin@example.com +# ServerName example.com +# ServerAlias subdomain.example.com + +### SETTINGS ### + + SetHandler "proxy:unix:/run/php/php$PHPVER-fpm.nextcloud.sock|fcgi://localhost" + + + DocumentRoot $NCPATH + + + Options Indexes FollowSymLinks + AllowOverride All + Require all granted + Satisfy Any + + + + Dav off + + + + # just in case if .htaccess gets disabled + Require all denied + + + # The following lines prevent .htaccess and .htpasswd files from being + # viewed by Web clients. + + Require all denied + + + # Disable HTTP TRACE method. + TraceEnable off + + # Disable HTTP TRACK method. + RewriteEngine On + RewriteCond %{REQUEST_METHOD} ^TRACK + RewriteRule .* - [R=405,L] + + SetEnv HOME $NCPATH + SetEnv HTTP_HOME $NCPATH + + # Avoid "Sabre\DAV\Exception\BadRequest: expected filesize XXXX got XXXX" + + RequestReadTimeout body=0 + + + +HTTP_CREATE + print_text_in_color "$IGreen" "$HTTP_CONF was successfully created." +fi + +# Generate $SSL_CONF +if [ ! -f $SSL_CONF ] +then + touch "$SSL_CONF" + cat << SSL_CREATE > "$SSL_CONF" + + Header add Strict-Transport-Security: "max-age=15768000;includeSubdomains" + SSLEngine on + +### YOUR SERVER ADDRESS ### +# ServerAdmin admin@example.com +# ServerName example.com +# ServerAlias subdomain.example.com + +### SETTINGS ### + + SetHandler "proxy:unix:/run/php/php$PHPVER-fpm.nextcloud.sock|fcgi://localhost" + + + DocumentRoot $NCPATH + + + Options Indexes FollowSymLinks + AllowOverride All + Require all granted + Satisfy Any + + + + Dav off + + + + # just in case if .htaccess gets disabled + Require all denied + + + # The following lines prevent .htaccess and .htpasswd files from being + # viewed by Web clients. + + Require all denied + + + # Disable HTTP TRACE method. + TraceEnable off + + # Disable HTTP TRACK method. + RewriteEngine On + RewriteCond %{REQUEST_METHOD} ^TRACK + RewriteRule .* - [R=405,L] + + SetEnv HOME $NCPATH + SetEnv HTTP_HOME $NCPATH + + # Avoid "Sabre\DAV\Exception\BadRequest: expected filesize XXXX got XXXX" + + RequestReadTimeout body=0 + + +### LOCATION OF CERT FILES ### + SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem + SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key + +SSL_CREATE + print_text_in_color "$IGreen" "$SSL_CONF was successfully created." +fi + +# Enable new config +a2ensite nextcloud_ssl_domain_self_signed.conf +a2ensite nextcloud_http_domain_self_signed.conf +a2dissite default-ssl +restart_webserver + +whiptail --title "Install apps or software" --checklist --separate-output "Automatically configure and install selected apps or software\nDeselect by pressing the spacebar" "$WT_HEIGHT" "$WT_WIDTH" 4 \ +"Calendar" " " on \ +"Contacts" " " on \ +"IssueTemplate" " " on \ +"PDFViewer" " " on \ +"Extract" " " on \ +"Text" " " on \ +"Mail" " " on \ +"Webmin" " " on 2>results + +while read -r -u 9 choice +do + case "$choice" in + Calendar) + install_and_enable_app calendar + ;; + Contacts) + install_and_enable_app contacts + ;; + IssueTemplate) + install_and_enable_app issuetemplate + ;; + PDFViewer) + install_and_enable_app files_pdfviewer + ;; + Extract) + if install_and_enable_app extract + then + install_if_not unrar + install_if_not p7zip + install_if_not p7zip-full + fi + ;; + Text) + install_and_enable_app text + ;; + Mail) + install_and_enable_app mail + ;; + Webmin) + run_app_script webmin + ;; + *) + ;; + esac +done 9< results +rm -f results + +# Get needed scripts for first bootup +check_command curl_to_dir "$GITHUB_REPO" nextcloud-startup-script.sh "$SCRIPTS" +check_command curl_to_dir "$GITHUB_REPO" lib.sh "$SCRIPTS" +download_static_script instruction +download_static_script history +download_static_script static_ip + +if home_sme_server +then + # Change nextcloud-startup-script.sh + check_command sed -i "s|VM|Home/SME Server|g" $SCRIPTS/nextcloud-startup-script.sh +fi + +# Make $SCRIPTS excutable +chmod +x -R "$SCRIPTS" +chown root:root -R "$SCRIPTS" + +# Prepare first bootup +check_command run_static_script change-ncadmin-profile +check_command run_static_script change-root-profile + +# Upgrade +apt update -q4 & spinner_loading +apt dist-upgrade -y + +# Remove LXD (always shows up as failed during boot) +apt purge lxd -y + +# Cleanup +apt autoremove -y +apt autoclean +find /root "/home/$UNIXUSER" -type f \( -name '*.sh*' -o -name '*.html*' -o -name '*.tar*' -o -name '*.zip*' \) -delete + +# Install virtual kernels for Hyper-V, and extra for UTF8 kernel module + Collabora and OnlyOffice +# Kernel 4.15 +apt install -y --install-recommends \ +linux-virtual \ +linux-tools-virtual \ +linux-cloud-tools-virtual \ +linux-image-virtual \ +linux-image-extra-virtual + +# Add aliases +if [ -f /root/.bash_aliases ] +then + if ! grep -q "nextcloud" /root/.bash_aliases + then +{ +echo "alias nextcloud_occ='sudo -u www-data php /var/www/nextcloud/occ'" +echo "alias run_update_nextcloud='bash /var/scripts/update.sh'" +} >> /root/.bash_aliases + fi +elif [ ! -f /root/.bash_aliases ] +then +{ +echo "alias nextcloud_occ='sudo -u www-data php /var/www/nextcloud/occ'" +echo "alias run_update_nextcloud='bash /var/scripts/update.sh'" +} > /root/.bash_aliases +fi + +# Set secure permissions final (./data/.htaccess has wrong permissions otherwise) +bash $SECURE & spinner_loading + +# Force MOTD to show correct number of updates +sudo /usr/lib/update-notifier/update-motd-updates-available --force + +# Reboot +print_text_in_color "$IGreen" "Installation done, system will now reboot..." +reboot diff --git a/nextcloud_update.sh b/nextcloud_update.sh new file mode 100755 index 0000000..c8718c5 --- /dev/null +++ b/nextcloud_update.sh @@ -0,0 +1,634 @@ +#!/bin/bash + +################################################################################################################# +# DO NOT USE THIS SCRIPT WHEN UPDATING NEXTCLOUD / YOUR SERVER! RUN `sudo bash /var/scripts/update.sh` INSTEAD. # +################################################################################################################# + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +NCDB=1 && NC_UPDATE=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset NC_UPDATE +unset NCDB + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin + +# Must be root +root_check + +# Check if dpkg or apt is running +is_process_running apt +is_process_running dpkg + +# Check if /boot is filled more than 90% and exit the script if that's the case since we don't want to end up with a broken system +if [ -d /boot ] +then + if [[ "$(df -h | grep /boot | awk '{print $5}' | cut -d "%" -f1)" -gt 90 ]] + then +msg_box "It seems like your boot drive is filled more than 90%. You can't proceed to upgrade since it probably will break your system + +To be able to proceed with the update you need to delete some old Linux kernels. If you need support, please visit: +https://shop.hanssonit.se/product/premium-support-per-30-minutes/" + exit + fi +fi + +# System Upgrade +if is_this_installed mysql-common +then + apt-mark hold mysql* + if is_this_installed mariadb-common + then + apt-mark hold mariadb* + fi +fi + +# Move all logs to new dir (2019-09-04) +if [ -d /var/log/ncvm/ ] +then + rsync -Aaxz /var/log/ncvm/ $VMLOGS + rm -Rf /var/log/ncvm/ +fi + +# Update docker-ce to overlay2 since devicemapper is deprecated +if [ -f /etc/systemd/system/docker.service ] +then + if grep -q "devicemapper" /etc/systemd/system/docker.service + then + print_text_in_color "$ICyan" "Changing to Overlay2 for Docker CE..." + print_text_in_color "$ICyan" "Please report any issues to $ISSUES." + run_static_script docker_overlay2 + elif grep -q "aufs" /etc/default/docker + then + apt-mark hold docker-ce + run_static_script docker_overlay2 + fi +fi + +apt update -q4 & spinner_loading +export DEBIAN_FRONTEND=noninteractive ; apt dist-upgrade -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" +if is_this_installed mysql-common +then + apt-mark unhold mysql* + print_text_in_color "$ICyan" "If you want to upgrade MySQL/MariaDB, please run 'sudo apt update && sudo apt dist-upgrade -y'" + sleep 2 + if is_this_installed mariadb-common + then + apt-mark unhold mariadb* + print_text_in_color "$ICyan" "If you want to upgrade MariaDB, please run 'sudo apt update && sudo apt dist-upgrade -y'" + sleep 2 + fi +fi + +# Update Netdata +if [ -d /etc/netdata ] +then + if [ -f /usr/src/netdata.git/netdata-updater.sh ] + then + run_app_script netdata + elif [ -f /usr/libexec/netdata-updater.sh ] + then + bash /usr/libexec/netdata-updater.sh + fi +fi + +# Update Redis PHP extension +print_text_in_color "$ICyan" "Trying to upgrade the Redis PECL extension..." +if version 18.04 "$DISTRO" 18.04.10; then + if ! pecl list | grep redis >/dev/null 2>&1 + then + if is_this_installed php"$PHPVER"-common + then + install_if_not php"$PHPVER"-dev + elif is_this_installed php7.0-common + then + install_if_not php7.0-dev + elif is_this_installed php7.1-common + then + install_if_not php7.1-dev + elif is_this_installed php7.3-common + then + install_if_not php7.3-dev + fi + apt purge php-redis -y + apt autoremove -y + pecl channel-update pecl.php.net + yes no | pecl install redis + service redis-server restart + # Check if redis.so is enabled + # PHP 7.0 apache + if [ -f /etc/php/7.0/apache2/php.ini ] + then + ! [[ "$(grep -R extension=redis.so /etc/php/7.0/apache2/php.ini)" == "extension=redis.so" ]] > /dev/null 2>&1 && echo "extension=redis.so" >> /etc/php/7.0/apache2/php.ini + # PHP "$PHPVER" apache + elif [ -f /etc/php/"$PHPVER"/apache2/php.ini ] + then + ! [[ "$(grep -R extension=redis.so /etc/php/"$PHPVER"/apache2/php.ini)" == "extension=redis.so" ]] > /dev/null 2>&1 && echo "extension=redis.so" >> /etc/php/"$PHPVER"/apache2/php.ini + # PHP "$PHPVER" fpm + elif [ -f "$PHP_INI" ] + then + ! [[ "$(grep -R extension=redis.so "$PHP_INI")" == "extension=redis.so" ]] > /dev/null 2>&1 && echo "extension=redis.so" >> "$PHP_INI" + fi + restart_webserver + elif pecl list | grep redis >/dev/null 2>&1 + then + if is_this_installed php"$PHPVER"-common + then + install_if_not php"$PHPVER"-dev + elif is_this_installed php7.0-common + then + install_if_not php7.0-dev + elif is_this_installed php7.1-common + then + install_if_not php7.1-dev + elif is_this_installed php7.3-common + then + install_if_not php7.3-dev + fi + pecl channel-update pecl.php.net + yes no | pecl upgrade redis + service redis-server restart + # Check if redis.so is enabled + # PHP 7.0 apache + if [ -f /etc/php/7.0/apache2/php.ini ] + then + ! [[ "$(grep -R extension=redis.so /etc/php/7.0/apache2/php.ini)" == "extension=redis.so" ]] > /dev/null 2>&1 && echo "extension=redis.so" >> /etc/php/7.0/apache2/php.ini + # PHP "$PHPVER" apache + elif [ -f /etc/php/"$PHPVER"/apache2/php.ini ] + then + ! [[ "$(grep -R extension=redis.so /etc/php/"$PHPVER"/apache2/php.ini)" == "extension=redis.so" ]] > /dev/null 2>&1 && echo "extension=redis.so" >> /etc/php/"$PHPVER"/apache2/php.ini + # PHP "$PHPVER" fpm + elif [ -f "$PHP_INI" ] + then + ! [[ "$(grep -R extension=redis.so "$PHP_INI")" == "extension=redis.so" ]] > /dev/null 2>&1 && echo "extension=redis.so" >> "$PHP_INI" + fi + restart_webserver + fi +else + msg_box "Ubuntu version $DISTRO must be at least 18.04 to upgrade Redis." +fi + +# Upgrade APCu and igbinary +if [ "${CURRENTVERSION%%.*}" -ge "17" ] +then + if [ -f "$PHP_INI" ] + then + print_text_in_color "$ICyan" "Trying to upgrade igbinary and APCu..." + if pecl list | grep igbinary >/dev/null 2>&1 + then + yes no | pecl upgrade igbinary + # Check if igbinary.so is enabled + if ! grep -qFx extension=igbinary.so "$PHP_INI" + then + echo "extension=igbinary.so" >> "$PHP_INI" + fi + fi + if pecl list | grep apcu >/dev/null 2>&1 + then + yes no | pecl upgrade apcu + # Check if apcu.so is enabled + if ! grep -qFx extension=apcu.so "$PHP_INI" + then + echo "extension=apcu.so" >> "$PHP_INI" + fi + fi + fi +fi + +# Update adminer +if [ -d $ADMINERDIR ] +then + print_text_in_color "$ICyan" "Updating Adminer..." + rm -f "$ADMINERDIR"/latest.php "$ADMINERDIR"/adminer.php + curl_to_dir "http://www.adminer.org" "latest.php" "$ADMINERDIR" + ln -s "$ADMINERDIR"/latest.php "$ADMINERDIR"/adminer.php +fi + +# Run watchtower to update all Docker images +if is_docker_running +then + # Remove old watchtower if existing + if does_this_docker_exist v2tec/watchtower + then + # Get Env values (https://github.com/koalaman/shellcheck/issues/1601) + get_env_values() { + # shellcheck disable=SC2016 + docker inspect -f '{{range $index, $value := .Config.Env}}{{$value}}{{println}}{{end}}' watchtower > env.list + } + get_env_values + + # Remove empty lines + sed -i '/^[[:space:]]*$/d' env.list + + # Get Cmd values + CmdDocker=$(docker inspect --format='{{.Config.Cmd}}' watchtower | cut -d "]" -f 1 | cut -d "[" -f 2;) + + # Check if env.list is empty and run the docker accordingly + if [ -s env.list ] + then + docker_prune_this v2tec/watchtower + docker run -d --restart=unless-stopped --name watchtower -v /var/run/docker.sock:/var/run/docker.sock --env-file ./env.list containrrr/watchtower "$CmdDocker" + rm -f env.list + else + docker_prune_this v2tec/watchtower + docker run -d --restart=unless-stopped --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower "$CmdDocker" + fi + fi + + # Get the new watchtower docker + if ! does_this_docker_exist containrrr/watchtower + then + docker run -d --restart=unless-stopped --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --cleanup --interval 3600 + fi +fi + +# Cleanup un-used packages +apt autoremove -y +apt autoclean + +# Update GRUB, just in case +update-grub + +# Remove update lists +rm /var/lib/apt/lists/* -r + +# Free some space (ZFS snapshots) +if is_this_installed libzfs2linux +then + if grep -rq ncdata /etc/mtab + then + run_static_script prune_zfs_snaphots + fi +fi + +# Fix bug in nextcloud.sh +CURRUSR="$(getent group sudo | cut -d: -f4 | cut -d, -f1)" +if grep -q "6.ifcfg.me" $SCRIPTS/nextcloud.sh &>/dev/null +then + rm -f "$SCRIPTS/nextcloud.sh" + download_static_script nextcloud + chown "$CURRUSR":"$CURRUSR" "$SCRIPTS/nextcloud.sh" + chmod +x "$SCRIPTS/nextcloud.sh" +elif [ -f $SCRIPTS/techandme.sh ] +then + rm -f "$SCRIPTS/techandme.sh" + download_static_script nextcloud + chown "$CURRUSR":"$CURRUSR" "$SCRIPTS/nextcloud.sh" + chmod +x "$SCRIPTS/nextcloud.sh" + if [ -f /home/"$CURRUSR"/.bash_profile ] + then + sed -i "s|techandme|nextcloud|g" /home/"$CURRUSR"/.bash_profile + elif [ -f /home/"$CURRUSR"/.profile ] + then + sed -i "s|techandme|nextcloud|g" /home/"$CURRUSR"/.profile + fi +fi + +# Set secure permissions +if [ ! -f "$SECURE" ] +then + mkdir -p "$SCRIPTS" + download_static_script setup_secure_permissions_nextcloud + chmod +x "$SECURE" +fi + +# Update all Nextcloud apps +if [ "${CURRENTVERSION%%.*}" -ge "15" ] +then + occ_command app:update --all +fi + +# Nextcloud 13 is required. +lowest_compatible_nc 13 + +if [ -f /tmp/minor.version ] +then + NCBAD=$(cat /tmp/minor.version) + NCVERSION=$(curl -s -m 900 $NCREPO/ | sed --silent 's/.*href="nextcloud-\([^"]\+\).zip.asc".*/\1/p' | sort --version-sort | grep "${CURRENTVERSION%%.*}" | tail -1) + export NCVERSION + export STABLEVERSION="nextcloud-$NCVERSION" + rm -f /tmp/minor.version +fi + +# Major versions unsupported +if [[ "${CURRENTVERSION%%.*}" -le "$NCBAD" ]] +then +msg_box "Please note that updates between multiple major versions are unsupported! Your situation is: +Current version: $CURRENTVERSION +Latest release: $NCVERSION + +It is best to keep your Nextcloud server upgraded regularly, and to install all point releases +and major releases without skipping any of them, as skipping releases increases the risk of +errors. Major releases are 13, 14, 15 and 16. Point releases are intermediate releases for each +major release. For example, 14.0.52 and 15.0.2 are point releases. + +Please contact T&M Hansson IT AB to help you with upgrading between major versions. +https://shop.hanssonit.se/product/upgrade-between-major-owncloud-nextcloud-versions/" + exit 1 +fi + +# Check if new version is larger than current version installed. +if version_gt "$NCVERSION" "$CURRENTVERSION" +then + print_text_in_color "$ICyan" "Latest release is: $NCVERSION. Current version is: $CURRENTVERSION." + print_text_in_color "$IGreen" "New version available! Upgrade continues..." +else + print_text_in_color "$ICyan" "Latest version is: $NCVERSION. Current version is: $CURRENTVERSION." + print_text_in_color "$ICyan" "No need to upgrade, this script will exit..." + exit 0 +fi + +# Check if PHP version is compatible with $NCVERSION +PHP_VER=71 +NC_VER=16 +if [ "${NCVERSION%%.*}" -ge "$NC_VER" ] +then + if [ "$(php -v | head -n 1 | cut -d " " -f 2 | cut -c 1,3)" -lt "$PHP_VER" ] + then +msg_box "Your PHP version isn't compatible with the new version of Nextcloud. Please upgrade your PHP stack and try again. + +If you need support, please visit https://shop.hanssonit.se/product/upgrade-php-version-including-dependencies/" + exit + fi +fi + +# Upgrade Nextcloud +if ! site_200 $NCREPO +then +msg_box "$NCREPO seems to be down, or temporarily not reachable. Please try again in a few minutes." + exit 1 +fi + +countdown "Backing up files and upgrading to Nextcloud $NCVERSION in 10 seconds... Press CTRL+C to abort." "10" + +# Stop Apache2 +check_command service apache2 stop + +# Create backup dir (/mnt/NCBACKUP/) +if [ ! -d "$BACKUP" ] +then + BACKUP=/var/NCBACKUP + mkdir -p $BACKUP +fi + +# Backup PostgreSQL +if is_this_installed postgresql-common +then + cd /tmp + if sudo -u postgres psql -c "SELECT 1 AS result FROM pg_database WHERE datname='$NCCONFIGDB'" | grep "1 row" > /dev/null + then + print_text_in_color "$ICyan" "Doing pgdump of $NCCONFIGDB..." + check_command sudo -u postgres pg_dump "$NCCONFIGDB" > "$BACKUP"/nextclouddb.sql + else + print_text_in_color "$ICyan" "Doing pgdump of all databases..." + check_command sudo -u postgres pg_dumpall > "$BACKUP"/alldatabases.sql + fi +fi + +# If MariaDB then: +mariadb_backup() { +MYCNF=/root/.my.cnf +MARIADBMYCNFPASS=$(grep "password" $MYCNF | sed -n "/password/s/^password='\(.*\)'$/\1/p") +NCCONFIGDB=$(grep "dbname" $NCPATH/config/config.php | awk '{print $3}' | sed "s/[',]//g") +NCCONFIGDBPASS=$(grep "dbpassword" $NCPATH/config/config.php | awk '{print $3}' | sed "s/[',]//g") +# Path to specific files +# Make sure old instaces can upgrade as well +if [ ! -f "$MYCNF" ] && [ -f /var/mysql_password.txt ] +then + regressionpw=$(cat /var/mysql_password.txt) +cat << LOGIN > "$MYCNF" +[client] +password='$regressionpw' +LOGIN + chmod 0600 $MYCNF + chown root:root $MYCNF + msg_box "Please restart the upgrade process, we fixed the password file $MYCNF." + exit 1 +elif [ -z "$MARIADBMYCNFPASS" ] && [ -f /var/mysql_password.txt ] +then + regressionpw=$(cat /var/mysql_password.txt) + { + echo "[client]" + echo "password='$regressionpw'" + } >> "$MYCNF" + msg_box "Please restart the upgrade process, we fixed the password file $MYCNF." + exit 1 +fi + +# Backup MariaDB +if mysql -u root -p"$MARIADBMYCNFPASS" -e "SHOW DATABASES LIKE '$NCCONFIGDB'" > /dev/null +then + print_text_in_color "$ICyan" "Doing mysqldump of $NCCONFIGDB..." + check_command mysqldump -u root -p"$MARIADBMYCNFPASS" -d "$NCCONFIGDB" > "$BACKUP"/nextclouddb.sql +else + print_text_in_color "$ICyan" "Doing mysqldump of all databases..." + check_command mysqldump -u root -p"$MARIADBMYCNFPASS" -d --all-databases > "$BACKUP"/alldatabases.sql +fi +} + +# Do the actual backup +if is_this_installed mysql-common && ! is_this_installed postgresql-common +then + mariadb_backup +elif is_this_installed mariadb-common && ! is_this_installed postgresql-common +then + mariadb_backup +fi + +# Check if backup exists and move to old +print_text_in_color "$ICyan" "Backing up data..." +DATE=$(date +%Y-%m-%d-%H%M%S) +if [ -d "$BACKUP" ] +then + mkdir -p "$BACKUP"-OLD/"$DATE" + install_if_not rsync + rsync -Aaxz "$BACKUP"/ "$BACKUP"-OLD/"$DATE" + rm -R "$BACKUP" + mkdir -p "$BACKUP" +fi + +# Do a backup of the ZFS mount +if is_this_installed libzfs2linux +then + if grep -rq ncdata /etc/mtab + then + check_multiverse + install_if_not zfs-auto-snapshot + sed -i "s|date --utc|date|g" /usr/sbin/zfs-auto-snapshot + check_command zfs-auto-snapshot -r ncdata + fi +fi + +# Backup data +for folders in config apps +do + if [[ "$(rsync -Aaxz $NCPATH/$folders $BACKUP)" -eq 0 ]] + then + BACKUP_OK=1 + else + unset BACKUP_OK + fi +done + +if [ -z $BACKUP_OK ] +then + msg_box "Backup was not OK. Please check $BACKUP and see if the folders are backed up properly" + exit 1 +else + printf "${IGreen}\nBackup OK!${Color_Off}\n" +fi + +# Download and validate Nextcloud package +check_command download_verify_nextcloud_stable + +if [ -f "$HTML/$STABLEVERSION.tar.bz2" ] +then + print_text_in_color "$ICyan" "$HTML/$STABLEVERSION.tar.bz2 exists" +else + msg_box "Aborting, something went wrong with the download" + exit 1 +fi + +if [ -d $BACKUP/config/ ] +then + print_text_in_color "$ICyan" "$BACKUP/config/ exists" +else +msg_box "Something went wrong with backing up your old nextcloud instance +Please check in $BACKUP if config/ folder exist." + exit 1 +fi + +if [ -d $BACKUP/apps/ ] +then + print_text_in_color "$ICyan" "$BACKUP/apps/ exists" + echo + print_text_in_color "$IGreen" "All files are backed up." + occ_command maintenance:mode --on + countdown "Removing old Nextcloud instance in 5 seconds..." "5" + rm -rf $NCPATH + print_text_in_color "$IGreen" "Extracting new package...." + tar -xjf "$HTML/$STABLEVERSION.tar.bz2" -C "$HTML" + rm "$HTML/$STABLEVERSION.tar.bz2" + print_text_in_color "$IGreen" "Restoring config to Nextcloud..." + rsync -Aaxz $BACKUP/config "$NCPATH"/ + bash $SECURE & spinner_loading + occ_command maintenance:mode --off + occ_command upgrade + # Optimize + print_text_in_color "$ICyan" "Optimizing Nextcloud..." + yes | occ_command db:convert-filecache-bigint + occ_command db:add-missing-indices +else +msg_box "Something went wrong with backing up your old nextcloud instance +Please check in $BACKUP if the folders exist." + exit 1 +fi + +# Update Bitwarden +if [ "$(docker ps -a >/dev/null 2>&1 && echo yes || echo no)" == "yes" ] +then + if docker ps -a --format '{{.Names}}' | grep -Eq "bitwarden"; + then + if is_this_installed apache2 + then + if [ -d /root/bwdata ] + then + curl_to_dir "https://raw.githubusercontent.com/bitwarden/server/master/scripts" "bitwarden.sh" "/root" + if [ -f /root/bitwarden.sh ] + then + print_text_in_color "$IGreen" "Upgrading Bitwarden..." + sleep 2 + bash /root/bitwarden.sh updateself + bash /root/bitwarden.sh update + fi + fi + fi + fi +fi + +# Start Apache2 +start_if_stopped apache2 + +# Just double check if the DB is started as well +if is_this_installed postgresql-common +then + if ! pgrep postgres >/dev/null 2>&1 + then + print_text_in_color "$ICyan" "Starting PostgreSQL..." + check_command service postgresql start + fi +fi + +# Recover apps that exists in the backed up apps folder +run_static_script recover_apps + +# Enable Apps +if [ -d "$SNAPDIR" ] +then + run_app_script spreedme +fi + +# Remove header for Nextcloud 14 (already in .htaccess) +if [ -f /etc/apache2/sites-available/"$(hostname -f)".conf ] +then + if grep -q 'Header always set Referrer-Policy' /etc/apache2/sites-available/"$(hostname -f)".conf + then + sed -i '/Header always set Referrer-Policy/d' /etc/apache2/sites-available/"$(hostname -f)".conf + restart_webserver + fi +fi + +# Change owner of $BACKUP folder to root +chown -R root:root "$BACKUP" + +# Pretty URLs +print_text_in_color "$ICyan" "Setting RewriteBase to \"/\" in config.php..." +chown -R www-data:www-data "$NCPATH" +occ_command config:system:set htaccess.RewriteBase --value="/" +occ_command maintenance:update:htaccess +bash "$SECURE" + +# Repair +occ_command maintenance:repair + +# Create $VMLOGS dir +if [ ! -d "$VMLOGS" ] +then + mkdir -p "$VMLOGS" +fi + +CURRENTVERSION_after=$(occ_command status | grep "versionstring" | awk '{print $3}') +if [[ "$NCVERSION" == "$CURRENTVERSION_after" ]] +then +msg_box "Latest version is: $NCVERSION. Current version is: $CURRENTVERSION_after. + +||| UPGRADE SUCCESS! ||| + +If you notice that some apps are disabled it's due to that they are not compatible with the new Nextcloud version. +To recover your old apps, please check $BACKUP/apps and copy them to $NCPATH/apps manually. + +Thank you for using T&M Hansson IT's updater!" + occ_command status + occ_command maintenance:mode --off + echo "NEXTCLOUD UPDATE success-$(date +"%Y%m%d")" >> "$VMLOGS"/update_run.log + exit 0 +else +msg_box "Latest version is: $NCVERSION. Current version is: $CURRENTVERSION_after. + +||| UPGRADE FAILED! ||| + +Your files are still backed up at $BACKUP. No worries! +Please report this issue to $ISSUES + +Maintenance mode is kept on." +occ_command status + exit 1 +fi diff --git a/static/adduser.sh b/static/adduser.sh new file mode 100755 index 0000000..568dd4d --- /dev/null +++ b/static/adduser.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +if [[ $UNIXUSER != "ncadmin" ]] +then +msg_box "Current user with sudo permissions is: $UNIXUSER. +This script will set up everything with that user. +If the field after ':' is blank you are probably running as a pure root user. +It's possible to install with root, but there will be minor errors. + +Please create a user with sudo permissions if you want an optimal installation. +The preferred user is 'ncadmin'." + if [[ "no" == $(ask_yes_or_no "Do you want to create a new user?") ]] + then + print_text_in_color "$ICyan" "Not adding another user..." + sleep 1 + else + read -r -p "Enter name of the new user: " NEWUSER + adduser --disabled-password --gecos "" "$NEWUSER" + sudo usermod -aG sudo "$NEWUSER" + usermod -s /bin/bash "$NEWUSER" + while true + do + sudo passwd "$NEWUSER" && break + done + sudo -u "$NEWUSER" sudo bash "$1" + fi +fi diff --git a/static/automatic_updates.sh b/static/automatic_updates.sh new file mode 100755 index 0000000..850b8b4 --- /dev/null +++ b/static/automatic_updates.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +print_text_in_color "$ICyan" "Configuring automatic updates..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +msg_box "This option will update your server every week on Saturdays at 18:00 (6 PM). +The update will run the built in script '$SCRIPTS/update.sh' which will update both the server packages and Nextcloud itself. + +You can read more about it here: https://www.techandme.se/nextcloud-update-is-now-fully-automated/ +Please keep in mind that automatic updates might fail hence it's important to have a proper backup in place if you plan to run this option. + +You can disable the automatic updates by entering the crontab file like this: +'sudo crontab -e -u root' +Then just put a hash (#) in front of the row that you want to disable. + +In the next step you will be able to choose to proceed or exit." + +if [[ "yes" == $(ask_yes_or_no "Do you want to enable automatic updates?") ]] +then + touch $VMLOGS/update.log + crontab -u root -l | { cat; echo "0 18 * * 6 $SCRIPTS/update.sh minor >> $VMLOGS/update.log"; } | crontab -u root - + if [[ "yes" == $(ask_yes_or_no "Do you want to reboot your server after every update? *recommended*") ]] + then + sed -i "s|exit|shutdown -r +1|g" "$SCRIPTS"/update.sh + echo "exit" >> "$SCRIPTS"/update.sh + fi +fi diff --git a/static/change-ncadmin-profile.sh b/static/change-ncadmin-profile.sh new file mode 100755 index 0000000..c042e71 --- /dev/null +++ b/static/change-ncadmin-profile.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +rm "/home/$UNIXUSER/.profile" + +cat <<-UNIXUSER-PROFILE > "$UNIXUSER_PROFILE" +# ~/.profile: executed by the command interpreter for login shells. +# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login +# exists. +# see /usr/share/doc/bash/examples/startup-files for examples. +# the files are located in the bash-doc package. +# the default umask is set in /etc/profile; for setting the umask +# for ssh logins, install and configure the libpam-umask package. +#umask 022 +# if running bash +if [ -n "$BASH_VERSION" ] +then + # include .bashrc if it exists + if [ -f "$HOME/.bashrc" ] + then + . "$HOME/.bashrc" + fi +fi +# set PATH so it includes user's private bin if it exists +if [ -d "$HOME/bin" ] +then + PATH="$HOME/bin:$PATH" +fi +bash /var/scripts/instruction.sh +bash /var/scripts/history.sh +sudo -i + +UNIXUSER-PROFILE + +chown "$UNIXUSER:$UNIXUSER" "$UNIXUSER_PROFILE" +chown "$UNIXUSER:$UNIXUSER" "$SCRIPTS/history.sh" +chown "$UNIXUSER:$UNIXUSER" "$SCRIPTS/instruction.sh" + +exit 0 diff --git a/static/change-root-profile.sh b/static/change-root-profile.sh new file mode 100755 index 0000000..d76e23a --- /dev/null +++ b/static/change-root-profile.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +[ -f /root/.profile ] && rm -f /root/.profile + +cat < "$ROOT_PROFILE" + +# ~/.profile: executed by Bourne-compatible login shells. + +if [ "$BASH" ] +then + if [ -f ~/.bashrc ] + then + . ~/.bashrc + fi +fi + +if [ -x /var/scripts/nextcloud-startup-script.sh ] +then + /var/scripts/nextcloud-startup-script.sh +fi + +if [ -x /var/scripts/history.sh ] +then + /var/scripts/history.sh +fi + +mesg n + +ROOT-PROFILE + +# Add Aliases +{ +echo "alias nextcloud_occ='sudo -u www-data php $NCPATH/occ'" +echo "alias run_update_nextcloud='bash $SCRIPTS/update.sh'" +} > /root/.bash_aliases + diff --git a/static/change_db_pass.sh b/static/change_db_pass.sh new file mode 100755 index 0000000..b4b495e --- /dev/null +++ b/static/change_db_pass.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +NCDBPASS=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset NCDBPASS + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Change PostgreSQL Password +cd /tmp +sudo -u www-data php "$NCPATH"/occ config:system:set dbpassword --value="$NEWPGPASS" + +if [ "$(sudo -u postgres psql -c "ALTER USER $NCUSER WITH PASSWORD '$NEWPGPASS'";)" == "ALTER ROLE" ] +then + sleep 1 +else + print_text_in_color "$IRed" "Changing PostgreSQL Nextcloud password failed." + sed -i "s| 'dbpassword' =>.*| 'dbpassword' => '$NCCONFIGDBPASS',|g" /var/www/nextcloud/config/config.php + print_text_in_color "$IRed" "Nothing is changed. Your old password is: $NCCONFIGDBPASS" + exit 1 +fi diff --git a/static/docker_overlay2.sh b/static/docker_overlay2.sh new file mode 100755 index 0000000..126862a --- /dev/null +++ b/static/docker_overlay2.sh @@ -0,0 +1,167 @@ +#!/bin/bash +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Must be root +root_check + +### Migrating Docker images to overlay2 ### +# https://www.techandme.se/changes-to-docker-ce-in-the-nextcloud-vm/ +# Credits to: https://gist.github.com/hydra1983/22b2bed38b4f5f56caa87c830c96378d + +# Make sure DOCKERBACKUP is created +if [ -f "$NCPATH"/config/config.php ] +then + NCDATA="$(grep 'datadir' "$NCPATH"/config/config.php | awk '{print $3}' | cut -d "'" -f2)" +fi +DOCKERBACKUP="$NCDATA/DOCKERBACKUP" +mkdir -p "$DOCKERBACKUP" + +# Check if aufs and don't run +if grep -q "aufs" /etc/default/docker +then +msg_box "This script doesn't support images that uses the AUFS driver, sorry + +You are welcome to send a PR, or report an issue here: $ISSUES" + exit 1 +fi + +readonly DB_FILE="$DOCKERBACKUP/images.db" +readonly IMG_DIR="$DOCKERBACKUP/images" + +save_images() { + print_text_in_color "$ICyan" "Create ${IMG_DIR}" + if [[ ! -d "${IMG_DIR}" ]]; then + mkdir "${IMG_DIR}" + fi + + print_text_in_color "$ICyan" "Create ${DB_FILE}" + docker images|grep -v 'IMAGE ID'|awk '{printf("%s %s %s\n", $1, $2, $3)}'|column -t > "${DB_FILE}" + + print_text_in_color "$ICyan" "Read ${DB_FILE}" + local images + while read -r image; do + images+=("$image"); + done <<< "$(cat "${DB_FILE}")" + + local name tag id + for image in "${images[@]}"; do + name=$(echo "$image"|awk '{print $1}') + tag=$(echo "$image"|awk '{print $2}') + id=$(echo "$image"|awk '{print $3}') + + if [[ "${id}" != "" ]]; then + local imgPath="${IMG_DIR}/${id}.dim" + + if [[ ! -f "${imgPath}" ]] ; then + print_text_in_color "$ICyan" "[DEBUG] save ${id} ${name}:${tag} to ${imgPath}" + (time docker save -o "${imgPath}" "${name}":"${tag}") 2>&1 | grep real + else + print_text_in_color "$ICyan" "[DEBUG] ${id} ${name}:${tag} already saved" + fi + fi + done +} + +load_images() { + if [[ ! -f "${DB_FILE}" ]]; then + print_text_in_color "$ICyan" "No ${DB_FILE} to read" + exit 0 + fi + + if [[ ! -d "${IMG_DIR}" ]]; then + print_text_in_color "$ICyan" "No ${IMG_DIR} to load images" + exit 0 + fi + + print_text_in_color "$ICyan" "Read ${DB_FILE}" + local images + while read -r image; do + images+=("$image"); + done <<< "$(cat "${DB_FILE}")" + + local name tag id + for image in "${images[@]}"; do + name=$(echo "$image"|awk '{print $1}') + tag=$(echo "$image"|awk '{print $2}') + id=$(echo "$image"|awk '{print $3}') + + if [[ "${id}" != "" ]]; then + local imgPath="${IMG_DIR}/${id}.dim" + + if [[ "$(docker images|grep "${id}" | grep "${name}" | grep "${tag}")" == "" ]]; then + if [[ "$(docker images|grep "${id}")" == "" ]]; then + print_text_in_color "$ICyan" "[DEBUG] load ${id} ${name}:${tag} from ${imgPath}" + docker load -i "${imgPath}" + else + print_text_in_color "$ICyan" "[DEBUG] tag ${id} as ${name}:${tag}" + docker tag "${id}" "${name}":"${tag}" + fi + else + print_text_in_color "$ICyan" "[DEBUG] ${id} ${name}:${tag} already loaded" + fi + fi + done +} + +# Save all docker images in one file +check_command docker ps -a > "$DOCKERBACKUP"/dockerps.txt +check_command docker images | sed '1d' | awk '{print $1 " " $2 " " $3}' > "$DOCKERBACKUP"/mydockersimages.list +msg_box "The following images will be saved to $DOCKERBACKUP/images + +$(cat "$DOCKERBACKUP"/mydockersimages.list) + +It may take a while so please be patient." + +check_command save_images + +# Set overlay2 +print_text_in_color "$ICyan" "Setting overlay2 in /etc/docker/daemon.json" + +cat << OVERLAY2 > /etc/docker/daemon.json +{ + "storage-driver": "overlay2" +} +OVERLAY2 +rm -f /etc/systemd/system/docker.service +systemctl restart docker.service +print_text_in_color "$ICyan" "Reloading daemon" +systemctl daemon-reload +print_text_in_color "$ICyan" "Restarting the docker service" +check_command systemctl restart docker +apt-mark unhold docker-ce + +# Remove old cached versions to avoid failures on update to new version +rm -Rf /var/cache/apt/archives/docker* +rm -Rf /var/cache/apt/archives/container* +rm -Rf /var/cache/apt/archives/aufs* + +# Upgrade docker to latest version +rm -Rf /var/lib/docker +apt update -q4 & spinner_loading +apt upgrade docker-ce -y + +# Load docker images back +print_text_in_color "$ICyan" "Importing saved docker images to overlay2..." +check_command load_images +msg_box "Your Docker images are now imported to overlay2, but not yet running. + +To start the images again, please run the appropriate 'docker run' command for each docker. +These are all the imported docker images: +$(cat "${DB_FILE}") + +You can also find the file with the imported docker images here: +$DB_FILE + +If you experiance any issues, please report them to $ISSUES." +rm -f "$DOCKERBACKUP"/mydockersimages.list diff --git a/static/format-chosen.sh b/static/format-chosen.sh new file mode 100755 index 0000000..d339040 --- /dev/null +++ b/static/format-chosen.sh @@ -0,0 +1,203 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check if root +root_check + +# Needs to be Ubuntu 18.04 and Multiverse +check_distro_version +check_multiverse + +LABEL_=ncdata +MOUNT_=/mnt/$LABEL_ + +format() { +# umount if mounted +umount /mnt/* &> /dev/null + +# mkdir if not existing +mkdir -p "$MOUNT_" + +# Check what Hypervisor disks are available +SYSVENDOR=$(cat /sys/devices/virtual/dmi/id/sys_vendor) +if [ "$SYSVENDOR" == "VMware, Inc." ]; +then + SYSNAME="VMware" + DEVTYPE=sdb +elif [ "$SYSVENDOR" == "Microsoft Corporation" ]; +then + SYSNAME="Hyper-V" + DEVTYPE=sdb +elif [ "$SYSVENDOR" == "innotek GmbH" ]; +then + SYSNAME="VirtualBox" + DEVTYPE=sdb +elif [ "$SYSVENDOR" == "Xen" ]; +then + SYSNAME="Xen/XCP-NG" + DEVTYPE=xvdb +elif [ "$SYSVENDOR" == "QEMU" ]; +then + SYSNAME="KVM/QEMU" + DEVTYPE=vdb +elif [ "$SYSVENDOR" == "DigitalOcean" ]; +then + SYSNAME="DigitalOcean" + DEVTYPE=sda +elif partprobe /dev/sdb &>/dev/null; +then + SYSNAME="machines" + DEVTYPE=sdb +else +msg_box "It seems like you didn't mount a second disk. +To be able to put the DATA on a second drive formatted as ZFS you need to add a second disk to this server. + +This script will now exit. Please mount a second disk and start over." +exit 1 +fi + +msg_box "You will now see a list with available devices. Choose the device where you want to put your nextcloud data. +Attention, the selected device will be formatted!" +AVAILABLEDEVICES="$(lsblk | grep 'disk' | awk '{print $1}')" +# https://github.com/koalaman/shellcheck/wiki/SC2206 +mapfile -t AVAILABLEDEVICES <<< "$AVAILABLEDEVICES" + +# Ask for user input +while + lsblk + read -r -e -p "Enter the drive for the nextcloud data:" -i "$DEVTYPE" userinput + userinput=$(echo "$userinput" | awk '{print $1}') + for disk in "${AVAILABLEDEVICES[@]}"; + do + [[ "$userinput" == "$disk" ]] && devtype_present=1 && DEVTYPE="$userinput" + done + [[ -z "${devtype_present+x}" ]] +do + printf "${BRed}$DEVTYPE is not a valid disk. Please try again.${Color_Off}\n" + : +done + +# Get the name of the drive +DISKTYPE=$(fdisk -l | grep "$DEVTYPE" | awk '{print $2}' | cut -d ":" -f1 | head -1) +if [ "$DISKTYPE" != "/dev/$DEVTYPE" ] +then +msg_box "It seems like your $SYSNAME secondary volume (/dev/$DEVTYPE) does not exist. +This script requires that you mount a second drive to hold the data. + +Please shutdown the server and mount a second drive, then start this script again. + +If you want help you can buy support in our shop: +https://shop.hanssonit.se/product/premium-support-per-30-minutes/" +exit 1 +fi + +# Check if ZFS utils are installed +install_if_not zfsutils-linux + +# Check still not mounted +#These functions return exit codes: 0 = found, 1 = not found +isMounted() { findmnt -rno SOURCE,TARGET "$1" >/dev/null;} #path or device +isDevMounted() { findmnt -rno SOURCE "$1" >/dev/null;} #device only +isPathMounted() { findmnt -rno TARGET "$1" >/dev/null;} #path only +isDevPartOfZFS() { zpool status | grep "$1" >/dev/null;} #device memeber of a zpool + +if isPathMounted "/mnt/ncdata"; #Spaces in path names are ok. +then +msg_box "/mnt/ncdata is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +if isDevMounted "/dev/$DEVTYPE"; +then +msg_box "/dev/$DEVTYPE is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +# Universal: +if isMounted "/mnt/ncdata"; +then +msg_box "/mnt/ncdata is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +if isMounted "/dev/${DEVTYPE}1"; +then +msg_box "/dev/${DEVTYPE}1 is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +if isDevPartOfZFS "$DEVTYPE"; +then +msg_box "/dev/$DEVTYPE is a member of a ZFS pool and needs to be removed from any zpool before you can run this script." + exit 1 +fi + +if lsblk -l -n | grep -v mmcblk | grep disk | awk '{ print $1 }' | tail -1 > /dev/null +then +msg_box "Formatting your $SYSNAME secondary volume ($DISKTYPE) when you hit OK. + +*** WARNING: ALL YOUR DATA WILL BE ERASED! ***" + if zpool list | grep "$LABEL_" > /dev/null + then + check_command zpool destroy "$LABEL_" + fi + check_command wipefs -a -f "$DISKTYPE" + sleep 0.5 + check_command zpool create -f -o ashift=12 "$LABEL_" "$DISKTYPE" + check_command zpool set failmode=continue "$LABEL_" + check_command zfs set mountpoint="$MOUNT_" "$LABEL_" + check_command zfs set compression=lz4 "$LABEL_" + check_command zfs set sync=standard "$LABEL_" + check_command zfs set xattr=sa "$LABEL_" + check_command zfs set primarycache=all "$LABEL_" + check_command zfs set atime=off "$LABEL_" + check_command zfs set recordsize=128k "$LABEL_" + check_command zfs set logbias=latency "$LABEL_" + +else +msg_box "It seems like /dev/$DEVTYPE does not exist. +This script requires that you mount a second drive to hold the data. + +Please shutdown the server and mount a second drive, then start this script again. + +If you want help you can buy support in our shop: +https://shop.hanssonit.se/product/premium-support-per-30-minutes/" +exit 1 +fi +} +format + +# Do a backup of the ZFS mount +if is_this_installed libzfs2linux +then + if grep -r $LABEL_ /etc/mtab + then + install_if_not zfs-auto-snapshot + sed -i "s|date --utc|date|g" /usr/sbin/zfs-auto-snapshot + fi +fi + +# Success! +if grep "$LABEL_" /etc/mtab +then +msg_box "$MOUNT_ mounted successfully as a ZFS volume. + +Automatic scrubbing is done monthly via a cronjob that you can find here: +/etc/cron.d/zfsutils-linux + +Automatic snapshots are taken with 'zfs-auto-snapshot'. You can list current snapshots with: +'sudo zfs list -t snapshot'. +Manpage is here: +http://manpages.ubuntu.com/manpages/bionic/man8/zfs-auto-snapshot.8.html + +CURRENT STATUS: +$(zpool status $LABEL_) + +$(zpool list)" +fi diff --git a/static/format-sda-nuc-server.sh b/static/format-sda-nuc-server.sh new file mode 100755 index 0000000..118bc1d --- /dev/null +++ b/static/format-sda-nuc-server.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check if root +root_check + +# Needs to be Ubuntu 18.04 and Multiverse +check_distro_version +check_multiverse + +LABEL_=ncdata +MOUNT_=/mnt/$LABEL_ + +format() { +# umount if mounted +umount /mnt/* &> /dev/null + +# mkdir if not existing +mkdir -p "$MOUNT_" + +# Check what Hypervisor disks are available +SYSVENDOR=$(cat /sys/devices/virtual/dmi/id/sys_vendor) +if [ "$SYSVENDOR" == "VMware, Inc." ]; +then + SYSNAME="VMware" + DEVTYPE=sda +elif [ "$SYSVENDOR" == "Microsoft Corporation" ]; +then + SYSNAME="Hyper-V" + DEVTYPE=sda +elif [ "$SYSVENDOR" == "innotek GmbH" ]; +then + SYSNAME="VirtualBox" + DEVTYPE=sda +elif [ "$SYSVENDOR" == "Xen" ]; +then + SYSNAME="Xen/XCP-NG" + DEVTYPE=xvdb +elif [ "$SYSVENDOR" == "QEMU" ]; +then + SYSNAME="KVM/QEMU" + DEVTYPE=vdb +elif [ "$SYSVENDOR" == "DigitalOcean" ]; +then + SYSNAME="DigitalOcean" + DEVTYPE=sda +elif partprobe /dev/sda &>/dev/null; +then + SYSNAME="machines" + DEVTYPE=sda +else +msg_box "It seems like you didn't mount a second disk. +To be able to put the DATA on a second drive formatted as ZFS you need to add a second disk to this server. + +This script will now exit. Please mount a second disk and start over." +exit 1 +fi + +# Get the name of the drive +DISKTYPE=$(fdisk -l | grep $DEVTYPE | awk '{print $2}' | cut -d ":" -f1 | head -1) +if [ "$DISKTYPE" != "/dev/$DEVTYPE" ] +then +msg_box "It seems like your $SYSNAME secondary volume (/dev/$DEVTYPE) does not exist. +This script requires that you mount a second drive to hold the data. + +Please shutdown the server and mount a second drive, then start this script again. + +If you want help you can buy support in our shop: +https://shop.hanssonit.se/product/premium-support-per-30-minutes/" +exit 1 +fi + +# Check if ZFS utils are installed +install_if_not zfsutils-linux + +# Check still not mounted +#These functions return exit codes: 0 = found, 1 = not found +isMounted() { findmnt -rno SOURCE,TARGET "$1" >/dev/null;} #path or device +isDevMounted() { findmnt -rno SOURCE "$1" >/dev/null;} #device only +isPathMounted() { findmnt -rno TARGET "$1" >/dev/null;} #path only +isDevPartOfZFS() { zpool status | grep "$1" >/dev/null;} #device memeber of a zpool + +if isPathMounted "/mnt/ncdata"; #Spaces in path names are ok. +then +msg_box "/mnt/ncdata is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +if isDevMounted "/dev/$DEVTYPE"; +then +msg_box "/dev/$DEVTYPE is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +# Universal: +if isMounted "/mnt/ncdata"; +then +msg_box "/mnt/ncdata is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +if isMounted "/dev/${DEVTYPE}1"; +then +msg_box "/dev/${DEVTYPE}1 is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +if isDevPartOfZFS "$DEVTYPE"; +then +msg_box "/dev/$DEVTYPE is a member of a ZFS pool and needs to be removed from any zpool before you can run this script." + exit 1 +fi + +if lsblk -l -n | grep -v mmcblk | grep disk | awk '{ print $1 }' | tail -1 > /dev/null +then +msg_box "Formatting your $SYSNAME secondary volume ($DISKTYPE) when you hit OK. + +*** WARNING: ALL YOUR DATA WILL BE ERASED! ***" + if zpool list | grep "$LABEL_" > /dev/null + then + check_command zpool destroy "$LABEL_" + fi + check_command wipefs -a -f "$DISKTYPE" + sleep 0.5 + check_command zpool create -f -o ashift=12 "$LABEL_" "$DISKTYPE" + check_command zpool set failmode=continue "$LABEL_" + check_command zfs set mountpoint="$MOUNT_" "$LABEL_" + check_command zfs set compression=lz4 "$LABEL_" + check_command zfs set sync=standard "$LABEL_" + check_command zfs set xattr=sa "$LABEL_" + check_command zfs set primarycache=all "$LABEL_" + check_command zfs set atime=off "$LABEL_" + check_command zfs set recordsize=128k "$LABEL_" + check_command zfs set logbias=latency "$LABEL_" + +else +msg_box "It seems like /dev/$DEVTYPE does not exist. +This script requires that you mount a second drive to hold the data. + +Please shutdown the server and mount a second drive, then start this script again. + +If you want help you can buy support in our shop: +https://shop.hanssonit.se/product/premium-support-per-30-minutes/" +exit 1 +fi +} +format + +# Do a backup of the ZFS mount +if is_this_installed libzfs2linux +then + if grep -r $LABEL_ /etc/mtab + then + install_if_not zfs-auto-snapshot + sed -i "s|date --utc|date|g" /usr/sbin/zfs-auto-snapshot + fi +fi + +# Success! +if grep "$LABEL_" /etc/mtab +then +msg_box "$MOUNT_ mounted successfully as a ZFS volume. + +Automatic scrubbing is done monthly via a cronjob that you can find here: +/etc/cron.d/zfsutils-linux + +Automatic snapshots are taken with 'zfs-auto-snapshot'. You can list current snapshots with: +'sudo zfs list -t snapshot'. +Manpage is here: +http://manpages.ubuntu.com/manpages/bionic/man8/zfs-auto-snapshot.8.html + +CURRENT STATUS: +$(zpool status $LABEL_) + +$(zpool list)" +fi diff --git a/static/format-sdb.sh b/static/format-sdb.sh new file mode 100755 index 0000000..915e0fd --- /dev/null +++ b/static/format-sdb.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check if root +root_check + +# Needs to be Ubuntu 18.04 and Multiverse +check_distro_version +check_multiverse + +LABEL_=ncdata +MOUNT_=/mnt/$LABEL_ + +format() { +# umount if mounted +umount /mnt/* &> /dev/null + +# mkdir if not existing +mkdir -p "$MOUNT_" + +# Check what Hypervisor disks are available +SYSVENDOR=$(cat /sys/devices/virtual/dmi/id/sys_vendor) +if [ "$SYSVENDOR" == "VMware, Inc." ]; +then + SYSNAME="VMware" + DEVTYPE=sdb +elif [ "$SYSVENDOR" == "Microsoft Corporation" ]; +then + SYSNAME="Hyper-V" + DEVTYPE=sdb +elif [ "$SYSVENDOR" == "innotek GmbH" ]; +then + SYSNAME="VirtualBox" + DEVTYPE=sdb +elif [ "$SYSVENDOR" == "Xen" ]; +then + SYSNAME="Xen/XCP-NG" + DEVTYPE=xvdb +elif [ "$SYSVENDOR" == "QEMU" ]; +then + SYSNAME="KVM/QEMU" + DEVTYPE=vdb +elif [ "$SYSVENDOR" == "DigitalOcean" ]; +then + SYSNAME="DigitalOcean" + DEVTYPE=sda +elif partprobe /dev/sdb &>/dev/null; +then + SYSNAME="machines" + DEVTYPE=sdb +else +msg_box "It seems like you didn't mount a second disk. +To be able to put the DATA on a second drive formatted as ZFS you need to add a second disk to this server. + +This script will now exit. Please mount a second disk and start over." +exit 1 +fi + +# Get the name of the drive +DISKTYPE=$(fdisk -l | grep $DEVTYPE | awk '{print $2}' | cut -d ":" -f1 | head -1) +if [ "$DISKTYPE" != "/dev/$DEVTYPE" ] +then +msg_box "It seems like your $SYSNAME secondary volume (/dev/$DEVTYPE) does not exist. +This script requires that you mount a second drive to hold the data. + +Please shutdown the server and mount a second drive, then start this script again. + +If you want help you can buy support in our shop: +https://shop.hanssonit.se/product/premium-support-per-30-minutes/" +exit 1 +fi + +# Check if ZFS utils are installed +install_if_not zfsutils-linux + +# Check still not mounted +#These functions return exit codes: 0 = found, 1 = not found +isMounted() { findmnt -rno SOURCE,TARGET "$1" >/dev/null;} #path or device +isDevMounted() { findmnt -rno SOURCE "$1" >/dev/null;} #device only +isPathMounted() { findmnt -rno TARGET "$1" >/dev/null;} #path only +isDevPartOfZFS() { zpool status | grep "$1" >/dev/null;} #device memeber of a zpool + +if isPathMounted "/mnt/ncdata"; #Spaces in path names are ok. +then +msg_box "/mnt/ncdata is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +if isDevMounted "/dev/$DEVTYPE"; +then +msg_box "/dev/$DEVTYPE is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +# Universal: +if isMounted "/mnt/ncdata"; +then +msg_box "/mnt/ncdata is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +if isMounted "/dev/${DEVTYPE}1"; +then +msg_box "/dev/${DEVTYPE}1 is mounted and need to be unmounted before you can run this script." + exit 1 +fi + +if isDevPartOfZFS "$DEVTYPE"; +then +msg_box "/dev/$DEVTYPE is a member of a ZFS pool and needs to be removed from any zpool before you can run this script." + exit 1 +fi + +if lsblk -l -n | grep -v mmcblk | grep disk | awk '{ print $1 }' | tail -1 > /dev/null +then +msg_box "Formatting your $SYSNAME secondary volume ($DISKTYPE) when you hit OK. + +*** WARNING: ALL YOUR DATA WILL BE ERASED! ***" + if zpool list | grep "$LABEL_" > /dev/null + then + check_command zpool destroy "$LABEL_" + fi + check_command wipefs -a -f "$DISKTYPE" + sleep 0.5 + check_command zpool create -f -o ashift=12 "$LABEL_" "$DISKTYPE" + check_command zpool set failmode=continue "$LABEL_" + check_command zfs set mountpoint="$MOUNT_" "$LABEL_" + check_command zfs set compression=lz4 "$LABEL_" + check_command zfs set sync=standard "$LABEL_" + check_command zfs set xattr=sa "$LABEL_" + check_command zfs set primarycache=all "$LABEL_" + check_command zfs set atime=off "$LABEL_" + check_command zfs set recordsize=128k "$LABEL_" + check_command zfs set logbias=latency "$LABEL_" + +else +msg_box "It seems like /dev/$DEVTYPE does not exist. +This script requires that you mount a second drive to hold the data. + +Please shutdown the server and mount a second drive, then start this script again. + +If you want help you can buy support in our shop: +https://shop.hanssonit.se/product/premium-support-per-30-minutes/" +exit 1 +fi +} +format + +# Do a backup of the ZFS mount +if is_this_installed libzfs2linux +then + if grep -r $LABEL_ /etc/mtab + then + install_if_not zfs-auto-snapshot + sed -i "s|date --utc|date|g" /usr/sbin/zfs-auto-snapshot + fi +fi + +# Success! +if grep "$LABEL_" /etc/mtab +then +msg_box "$MOUNT_ mounted successfully as a ZFS volume. + +Automatic scrubbing is done monthly via a cronjob that you can find here: +/etc/cron.d/zfsutils-linux + +Automatic snapshots are taken with 'zfs-auto-snapshot'. You can list current snapshots with: +'sudo zfs list -t snapshot'. +Manpage is here: +http://manpages.ubuntu.com/manpages/bionic/man8/zfs-auto-snapshot.8.html + +CURRENT STATUS: +$(zpool status $LABEL_) + +$(zpool list)" +fi diff --git a/static/history.sh b/static/history.sh new file mode 100755 index 0000000..1d33917 --- /dev/null +++ b/static/history.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +truncate -s0 "$HOME/.bash_history" + +exit 0 diff --git a/static/index.php b/static/index.php new file mode 100755 index 0000000..582ff9f --- /dev/null +++ b/static/index.php @@ -0,0 +1,148 @@ + + + + Nextcloud VM + + + + +
+ + +
+
+

Thank you for downloading the Nextcloud VM, you made a good choice! If you see this page, you have run the first setup, and you are now ready to start using Nextcloud on your new server. Congratulations! :)

+

We have set everything up for you and the only thing you have to do now is to login. You can find login details in the middle of this page.

+

Don't hesitate to ask if you have any questions. You can ask for help in our community support channels, or buy hands on support from T&M Hansson IT AB. You can also check the documentation.

+
+ +

Access Nextcloud

+ +
+

Use the following address: +

+ +

+

Note: Please accept the warning in the browser if you have a self-signed certificate.
+ +

It's recomended to get your own certificate and replace the self-signed certificate to your own. + The easiest way to get a real SSL certificate is to run the Lets' Encrypt script included on this server.
+ Just run 'sudo bash /var/scripts/activate-ssl.sh' from your terminal and follow the instructions. +

+ Login details +

+
+ +

Access Webmin

+ +
+

Use the following address: +

+ +

+

Note: Please accept the warning in the browser if you have a self-signed certificate.
+

+ Login details +

+

Note: To access Webmin externally you have to open port 10000 in your router, it's not recomended though due to security concerns.

+
+ +

Access Adminer

+ +
+

Use one of the following addresses, HTTPS is preffered: +

+ +

+

Note: Please accept the warning in the browser if you connect via HTTPS.

+

+ Login details +

+

Note: Your LAN IP is set as approved in /etc/apache2/conf-available/adminer.conf, all other access is forbidden.

+
+ +

Follow us on Social Media

+ +
+

If you want to get the latest news and updates, please consider following us! We are very active on Twitter, and post some videos from time to time on Youtube. It might be worth checking out. ;)

+
+

+ +
+ + diff --git a/static/instruction.sh b/static/instruction.sh new file mode 100755 index 0000000..b275d2e --- /dev/null +++ b/static/instruction.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +VMLOGS=/var/log/nextcloud +BIGreen='\e[1;92m' # Green +IGreen='\e[0;92m' # Green +Color_Off='\e[0m' # Text Reset + +clear +cat << INST1 ++-----------------------------------------------------------------------+ +| Welcome to the first setup of your own Nextcloud Server! :) | +| | +INST1 +echo -e "|" "${IGreen}To run the startup script type the sudoer password, then hit [ENTER].${Color_Off} |" +echo -e "|" "${IGreen}The default sudoer password is: ${BIGreen}nextcloud${IGreen}${Color_Off} |" +cat << INST2 +| | +| You can find the complete install instructions here: | +| Nextcloud VM = https://bit.ly/2S8eGfS | +| Nextcloud Home/SME Server = https://bit.ly/2k2TNaM | +| | +| To be 100% sure that all the keystrokes work correctly (like @), | +| please use an SSH terminal like Putty. You can download it here: | +| https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html | +| Connect like this: ncadmin@local.IP.of.this.server | +| | +| You can schedule the Nextcloud update process using a cron job. | +| This is done using a script built into this server that automatically | +| updates Nextcloud, sets secure permissions, and logs the successful | +| update to $VMLOGS/update_run.log | +| Just choose to configure it when asked to do so later in this script. | +| | +| ###################### T&M Hansson IT - $(date +"%Y") ###################### | ++-----------------------------------------------------------------------+ +INST2 + +exit 0 diff --git a/static/modsecurity.sh b/static/modsecurity.sh new file mode 100755 index 0000000..6358742 --- /dev/null +++ b/static/modsecurity.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +print_text_in_color "$ICyan" "Installing ModSecurity..." + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +# Add modsecurity +apt update -q4 & spinner_loading +install_if_not libapache2-mod-security2 +install_if_not modsecurity-crs +mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf + +msg_box "WARNING WARNING WARNING WARNING WARNING WARNING: + +Do not enable active defence if you don't know what you're doing! +It will break OnlyOffice, and it may break other stuff as well in Nextcloud as it's +blocking access to files automatically. + +You can monitor the audit log by typing this command in your shell: +tail -f /var/log/apache2/modsec_audit.log + +You can disable it by typing this command in your shell: +sed -i 's/SecRuleEngine .*/SecRuleEngine DetectionOnly/g' /etc/modsecurity/modsecurity.conf + +YOU HAVE BEEN WARNED." +if [[ "yes" == $(ask_yes_or_no "Do you want to enable active defence?") ]] +then + sed -i 's|SecRuleEngine .*|SecRuleEngine on|g' /etc/modsecurity/modsecurity.conf +fi + +cat << MODSECWHITE > "/etc/modsecurity/whitelist.conf" + +# VIDEOS + SecRuleRemoveById 958291 # Range Header Checks + SecRuleRemoveById 981203 # Correlated Attack Attempt + + # PDF + SecRuleRemoveById 950109 # Check URL encodings + + # ADMIN (webdav) + SecRuleRemoveById 960024 # Repeatative Non-Word Chars (heuristic) + SecRuleRemoveById 981173 # SQL Injection Character Anomaly Usage + SecRuleRemoveById 981204 # Correlated Attack Attempt + SecRuleRemoveById 981243 # PHPIDS - Converted SQLI Filters + SecRuleRemoveById 981245 # PHPIDS - Converted SQLI Filters + SecRuleRemoveById 981246 # PHPIDS - Converted SQLI Filters + SecRuleRemoveById 981318 # String Termination/Statement Ending Injection Testing + SecRuleRemoveById 973332 # XSS Filters from IE + SecRuleRemoveById 973338 # XSS Filters - Category 3 + SecRuleRemoveById 981143 # CSRF Protections ( TODO edit LocationMatch filter ) + + # COMING BACK FROM OLD SESSION + SecRuleRemoveById 970903 # Microsoft Office document properties leakage + + # NOTES APP + SecRuleRemoveById 981401 # Content-Type Response Header is Missing and X-Content-Type-Options is either missing or not set to 'nosniff' + SecRuleRemoveById 200002 # Failed to parse request body + + # UPLOADS ( 20 MB max excluding file size ) + SecRequestBodyNoFilesLimit 20971520 + + # GENERAL + SecRuleRemoveById 960017 # Host header is a numeric IP address + + # SAMEORIGN + SecRuleRemoveById 911100 # fpm socket + + # REGISTERED WARNINGS, BUT DID NOT HAVE TO DISABLE THEM + #SecRuleRemoveById 981220 900046 981407 + #SecRuleRemoveById 981222 981405 981185 981184 + +MODSECWHITE + +# Don't log in Apache2 error.log, only in a seperate log (/var/log/apache2/modsec_audit.log) +check_command sed -i 's|SecDefaultAction "phase:1,log,auditlog,pass"|# SecDefaultAction "phase:1,log,auditlog,pass"|g' /etc/modsecurity/crs/crs-setup.conf +check_command sed -i 's|SecDefaultAction "phase:2,log,auditlog,pass"|# SecDefaultAction "phase:2,log,auditlog,pass"|g' /etc/modsecurity/crs/crs-setup.conf +check_command sed -i 's|# SecDefaultAction "phase:1,nolog,auditlog,pass"|SecDefaultAction "phase:1,nolog,auditlog,pass"|g' /etc/modsecurity/crs/crs-setup.conf +check_command sed -i 's|# SecDefaultAction "phase:2,nolog,auditlog,pass"|SecDefaultAction "phase:2,nolog,auditlog,pass"|g' /etc/modsecurity/crs/crs-setup.conf + +if [ -f /etc/modsecurity/whitelist.conf ] +then + print_text_in_color "$IGreen" "ModSecurity activated!" + restart_webserver +fi diff --git a/static/nextcloud.sh b/static/nextcloud.sh new file mode 100755 index 0000000..357b434 --- /dev/null +++ b/static/nextcloud.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +WANIP6=$(curl -s -k -m 5 https://ipv6bot.whatismyipaddress.com) +WANIP4=$(curl -s -k -m 5 https://ipv4bot.whatismyipaddress.com) +ADDRESS=$(hostname -I | cut -d ' ' -f 1) + +clear +figlet -f small Nextcloud +echo "https://www.hanssonit.se/nextcloud-vm" +echo +echo +echo "Hostname: $(hostname -s)" +echo "WAN IPv4: $WANIP4" +echo "WAN IPv6: $WANIP6" +echo "LAN IPv4: $ADDRESS" +echo +exit 0 diff --git a/static/nhss_index.php b/static/nhss_index.php new file mode 100755 index 0000000..2d9e8d8 --- /dev/null +++ b/static/nhss_index.php @@ -0,0 +1,148 @@ + + + + Nextcloud Home/SME Server + + + + +
+ + +
+
+

Thank you for purchasing the Nextcloud Home/SME Server, you made a good choice! If you see this page, you have run the first setup, and you are now ready to start using Nextcloud on your new server. Congratulations! :)

+

We have set everything up for you and the only thing you have to do now is to login. You can find login details in the middle of this page.

+

Don't hesitate to ask if you have any questions. You can ask for help in our community support channels, or buy hands on support from T&M Hansson IT AB. You can also check the documentation.

+
+ +

Access Nextcloud

+ +
+

Use the following address: +

+ +

+

Note: Please accept the warning in the browser if you have a self-signed certificate.
+ +

It's recomended to get your own certificate and replace the self-signed certificate to your own. + The easiest way to get a real SSL certificate is to run the Lets' Encrypt script included on this server.
+ Just run 'sudo bash /var/scripts/activate-ssl.sh' from your terminal and follow the instructions. +

+ Login details +

+
+ +

Access Webmin

+ +
+

Use the following address: +

+ +

+

Note: Please accept the warning in the browser if you have a self-signed certificate.
+

+ Login details +

+

Note: To access Webmin externally you have to open port 10000 in your router, it's not recomended though due to security concerns.

+
+ +

Access Adminer

+ +
+

Use one of the following addresses, HTTPS is preffered: +

+ +

+

Note: Please accept the warning in the browser if you connect via HTTPS.

+

+ Login details +

+

Note: Your LAN IP is set as approved in /etc/apache2/conf-available/adminer.conf, all other access is forbidden.

+
+ +

Follow us on Social Media

+ +
+

If you want to get the latest news and updates, please consider following us! We are very active on Twitter, and post some videos from time to time on Youtube. It might be worth checking out. ;)

+
+

+ +
+ + diff --git a/static/ntpdate.sh b/static/ntpdate.sh new file mode 100755 index 0000000..fceafb2 --- /dev/null +++ b/static/ntpdate.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +if site_200 google.com +then + ntpdate -s 1.se.pool.ntp.org +fi +exit diff --git a/static/prune_zfs_snaphots.sh b/static/prune_zfs_snaphots.sh new file mode 100755 index 0000000..b06ab5a --- /dev/null +++ b/static/prune_zfs_snaphots.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Must be root +root_check + +if [ -d $NCDATA ] +then + if is_this_installed zfs-auto-snapshot + then + if [ "$(df -h $NCDATA | awk '{print $5}' | tail -1 | cut -d "%" -f1)" -gt 85 ] + then + # Notify user + # notify_user_gui "Disk space almost full!" "The disk space for ncdata is almost full. We have automatically deleted ZFS snapshots older than 8 weeks to free up some space. Please check $VMLOGS/zfs_prune.log for the results." + # On screen information +msg_box "Your disk space is almost full (more than 85%). + +To solve that, we will now delete ZFS snapshots older than 8 weeks + +The script will also delete everything in trashbin for all users to free up some space." + countdown "To abort, please press CTRL+C within 10 seconds." 10 + # Get the latest prune script + if [ ! -f $SCRIPTS/zfs-prune-snapshots ] + then + check_command curl_to_dir "https://raw.githubusercontent.com/bahamas10/zfs-prune-snapshots/master/" "zfs-prune-snapshots" "$SCRIPTS" + fi + check_command chmod +x "$SCRIPTS"/zfs-prune-snapshots + # Prune! + cd "$SCRIPTS" + if [ ! -d "$VMLOGS" ] + then + mkdir -p "$VMLOGS" + fi + touch $VMLOGS/zfs_prune.log + ./zfs-prune-snapshots 8w ncdata >> $VMLOGS/zfs_prune.log + occ_command trashbin:cleanup --all-users + fi + fi +fi diff --git a/static/recover_apps.py b/static/recover_apps.py new file mode 100755 index 0000000..8ff4f0f --- /dev/null +++ b/static/recover_apps.py @@ -0,0 +1,16 @@ +import glob, json, os, subprocess, requests + +nc_path = '/var/www/nextcloud/apps/' +backup_path = '/var/NCBACKUP/apps/' +shipped_url = 'http://raw.githubusercontent.com/nextcloud/server/master/core/shipped.json' + +json_data = requests.get(shipped_url, timeout=60).json() +shipped_apps = json_data['shippedApps'] + json_data['alwaysEnabled'] + +installed_dirs = set(os.path.basename(path) for path in glob.glob(backup_path + '*')) +missing_dirs = installed_dirs.difference(shipped_apps) + +for d in missing_dirs: +# subprocess.call(['rsync', '-Aax', os.path.join(backup_path, d), nc_path]) +# subprocess.call(['sudo', '-u', 'www-data', '/var/www/nextcloud/occ', 'app:enable', d]) + subprocess.call(['sudo', '-u', 'www-data', '/var/www/nextcloud/occ', 'app:install', d]) diff --git a/static/redis-server-ubuntu.sh b/static/redis-server-ubuntu.sh new file mode 100755 index 0000000..3af674f --- /dev/null +++ b/static/redis-server-ubuntu.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Must be root +root_check + +# Check Ubuntu version +check_distro_version + +# Check if dir exists +if [ ! -d $SCRIPTS ] +then + mkdir -p $SCRIPTS +fi + +# Install Redis +install_if_not php"$PHPVER"-dev +pecl channel-update pecl.php.net +if ! yes no | pecl install -Z redis +then + msg_box "PHP module installation failed" +exit 1 +else + printf "${IGreen}\nPHP module installation OK!${Color_Off}\n" +fi +install_if_not redis-server + +# Setting direct to PHP-FPM as it's installed with PECL (globally doesn't work) +print_text_in_color "$ICyan" "Adding extension=redis.so to $PHP_INI..." +echo 'extension=redis.so' >> "$PHP_INI" + +# Prepare for adding redis configuration +sed -i "s|);||g" $NCPATH/config/config.php + +# Add the needed config to Nextclouds config.php +cat <> $NCPATH/config/config.php + 'memcache.local' => '\\OC\\Memcache\\APCu', + 'filelocking.enabled' => true, + 'memcache.distributed' => '\\OC\\Memcache\\Redis', + 'memcache.locking' => '\\OC\\Memcache\\Redis', + 'redis' => + array ( + 'host' => '$REDIS_SOCK', + 'port' => 0, + 'timeout' => 0.5, + 'dbindex' => 0, + 'password' => '$REDIS_PASS', + ), +); +ADD_TO_CONFIG + +## Redis performance tweaks ## +if ! grep -Fxq "vm.overcommit_memory = 1" /etc/sysctl.conf +then + echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf +fi + +# Disable THP +if ! grep -Fxq "never" /sys/kernel/mm/transparent_hugepage/enabled +then + echo "never" > /sys/kernel/mm/transparent_hugepage/enabled +fi + +# Raise TCP backlog +#if ! grep -Fxq "net.core.somaxconn" /proc/sys/net/core/somaxconn +#then +# sed -i "s|net.core.somaxconn.*||g" /etc/sysctl.conf +# sysctl -w net.core.somaxconn=512 +# echo "net.core.somaxconn = 512" >> /etc/sysctl.conf +#fi +sed -i "s|# unixsocket .*|unixsocket $REDIS_SOCK|g" $REDIS_CONF +sed -i "s|# unixsocketperm .*|unixsocketperm 777|g" $REDIS_CONF +sed -i "s|^port.*|port 0|" $REDIS_CONF +sed -i "s|# requirepass .*|requirepass $REDIS_PASS|g" $REDIS_CONF +sed -i 's|# rename-command CONFIG ""|rename-command CONFIG ""|' $REDIS_CONF +redis-cli SHUTDOWN + +# Secure Redis +chown redis:root /etc/redis/redis.conf +chmod 600 /etc/redis/redis.conf + +apt update -q4 & spinner_loading +apt autoremove -y +apt autoclean + +exit diff --git a/static/security.sh b/static/security.sh new file mode 100755 index 0000000..2765704 --- /dev/null +++ b/static/security.sh @@ -0,0 +1,121 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# REMOVE disable of SC2154 WHEN PUTTING SPAMHAUS IN PRODUCTION (it's just to fixing travis for now) +# shellcheck disable=2034,2059,SC2154 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +print_text_in_color "$ICyan" "Installing Extra Security..." + +# Based on: http://www.techrepublic.com/blog/smb-technologist/secure-your-apache-server-from-ddos-slowloris-and-dns-injection-attacks/ + +# Protect against DDOS +apt update -q4 & spinner_loading +apt -y install libapache2-mod-evasive +mkdir -p /var/log/apache2/evasive +chown -R www-data:root /var/log/apache2/evasive +if [ ! -f "$ENVASIVE" ] +then + touch "$ENVASIVE" + cat << ENVASIVE > "$ENVASIVE" +DOSHashTableSize 2048 +DOSPageCount 20 # maximum number of requests for the same page +DOSSiteCount 300 # total number of requests for any object by the same client IP on the same listener +DOSPageInterval 1.0 # interval for the page count threshold +DOSSiteInterval 1.0 # interval for the site count threshold +DOSBlockingPeriod 10.0 # time that a client IP will be blocked for +DOSLogDir +ENVASIVE +fi + +# Protect against Slowloris +#apt -y install libapache2-mod-qos +a2enmod reqtimeout # http://httpd.apache.org/docs/2.4/mod/mod_reqtimeout.html + +# Don't enable SpamHaus now as it's now working anyway +# REMOVE disable of SC2154 WHEN PUTTING SPAMHAUS IN PRODUCTION (it's just to fixing travis for now) +exit + +# Protect against DNS Injection +# Insipired by: https://www.c-rieger.de/nextcloud-13-nginx-installation-guide-for-ubuntu-18-04-lts/#spamhausproject + +# shellcheck disable=SC2016 +DATE='$(date +%Y-%m-%d)' +cat << SPAMHAUS_ENABLE > "$SCRIPTS/spamhaus_cronjob.sh" +#!/bin/bash +# Thanks to @ank0m +EXEC_DATE='date +%Y-%m-%d' +SPAMHAUS_DROP="/usr/local/src/drop.txt" +SPAMHAUS_eDROP="/usr/local/src/edrop.txt" +URL="https://www.spamhaus.org/drop/drop.txt" +eURL="https://www.spamhaus.org/drop/edrop.txt" +DROP_ADD_TO_UFW="/usr/local/src/DROP2.txt" +eDROP_ADD_TO_UFW="/usr/local/src/eDROP2.txt" +DROP_ARCHIVE_FILE="/usr/local/src/DROP_{$EXEC_DATE}" +eDROP_ARCHIVE_FILE="/usr/local/src/eDROP_{$EXEC_DATE}" +# All credits for the following BLACKLISTS goes to "The Spamhaus Project" - https://www.spamhaus.org +echo "Start time: $(date)" +echo " " +echo "Download daily DROP file:" +curl -fsSL "$URL" > $SPAMHAUS_DROP +grep -v '^;' $SPAMHAUS_DROP | cut -d ' ' -f 1 > $DROP_ADD_TO_UFW +echo " " +echo "Extract DROP IP addresses and add to UFW:" +cat $DROP_ADD_TO_UFW | while read line +do +/usr/sbin/ufw insert 1 deny from "$line" comment 'DROP_Blacklisted_IPs' +done +echo " " +echo "Downloading eDROP list and import to UFW" +echo " " +echo "Download daily eDROP file:" +curl -fsSL "$eURL" > $SPAMHAUS_eDROP +grep -v '^;' $SPAMHAUS_eDROP | cut -d ' ' -f 1 > $eDROP_ADD_TO_UFW +echo " " +echo "Extract eDROP IP addresses and add to UFW:" +cat $eDROP_ADD_TO_UFW | while read line +do +/usr/sbin/ufw insert 1 deny from "$line" comment 'eDROP_Blacklisted_IPs' +done +echo " " +##### +## To remove or revert these rules, keep the list of IPs! +## Run a command like so to remove the rules: +# while read line; do ufw delete deny from $line; done < $ARCHIVE_FILE +##### +echo "Backup DROP IP address list:" +mv $DROP_ADD_TO_UFW $DROP_ARCHIVE_FILE +echo " " +echo "Backup eDROP IP address list:" +mv $eDROP_ADD_TO_UFW $eDROP_ARCHIVE_FILE +echo " " +echo End time: $(date) +SPAMHAUS_ENABLE + +# Make the file executable +chmod +x "$SCRIPTS"/spamhaus_cronjob.sh + +# Add it to crontab +(crontab -l ; echo "10 2 * * * $SCRIPTS/spamhaus_crontab.sh 2>&1") | crontab -u root - + +# Run it for the first time +check_command bash "$SCRIPTS"/spamhaus_cronjob.sh + +# Enable $SPAMHAUS +if sed -i "s|#MS_WhiteList /etc/spamhaus.wl|MS_WhiteList $SPAMHAUS|g" /etc/apache2/mods-enabled/spamhaus.conf +then + print_text_in_color "$IGreen" "Security added!" + restart_webserver +fi diff --git a/static/setup_secure_permissions_nextcloud.sh b/static/setup_secure_permissions_nextcloud.sh new file mode 100755 index 0000000..9778a7a --- /dev/null +++ b/static/setup_secure_permissions_nextcloud.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059,2012 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Check if root +root_check + +htuser='www-data' +htgroup='www-data' +rootuser='root' + +# Only check for existing datadir if Nextcloud is installed +if [ -f "$NCPATH"/config/config.php ] +then + NCDATA="$(grep 'datadir' "$NCPATH"/config/config.php | awk '{print $3}' | cut -d "'" -f2)" +fi + +print_text_in_color "$IGreen" "Setting secure permissions..." +print_text_in_color "$ICyan" "Creating possible missing Directories" +mkdir -p "$NCPATH"/data +mkdir -p "$NCPATH"/updater +mkdir -p "$VMLOGS" +mkdir -p "$NCDATA" + +if ! [ -f "$VMLOGS/nextcloud.log" ] +then + touch "$VMLOGS/nextcloud.log" +fi + +if ! [ -f "$VMLOGS/audit.log" ] +then + touch "$VMLOGS/audit.log" +fi + +print_text_in_color "$ICyan" "chmod Files and Directories" +find "${NCPATH}"/ -type f -print0 | xargs -0 chmod 0640 +find "${VMLOGS}"/nextcloud.log -type f -print0 | xargs -0 chmod 0640 +find "${VMLOGS}"/audit.log -type f -print0 | xargs -0 chmod 0640 +find "${NCPATH}"/ -type d -print0 | xargs -0 chmod 0750 + +print_text_in_color "$ICyan" "chown Directories" +chown -R "${rootuser}":"${htgroup}" "${NCPATH}"/ +chown -R "${htuser}":"${htgroup}" "${VMLOGS}"/nextcloud.log +chown -R "${htuser}":"${htgroup}" "${VMLOGS}"/audit.log +chown -R "${htuser}":"${htgroup}" "${NCPATH}"/apps/ +chown -R "${htuser}":"${htgroup}" "${NCPATH}"/config/ +chown -R "${htuser}":"${htgroup}" "${NCPATH}"/themes/ +chown -R "${htuser}":"${htgroup}" "${NCPATH}"/updater/ +if ! [ "$(ls -ld "${NCDATA}" | awk '{print$3$4}')" == "${htuser}""${htgroup}" ] +then + chown -R "${htuser}":"${htgroup}" "${NCDATA}"/ +fi + +chmod +x "${NCPATH}"/occ + +print_text_in_color "$ICyan" "chmod/chown .htaccess" +if [ -f "${NCPATH}"/.htaccess ] +then + chmod 0644 "${NCPATH}"/.htaccess + chown "${rootuser}":"${htgroup}" "${NCPATH}"/.htaccess +fi +if [ -f "${NCDATA}"/.htaccess ] +then + chmod 0644 "${NCDATA}"/.htaccess + chown "${rootuser}":"${htgroup}" "${NCDATA}"/.htaccess +fi + diff --git a/static/static_ip.sh b/static/static_ip.sh new file mode 100755 index 0000000..c9c0bff --- /dev/null +++ b/static/static_ip.sh @@ -0,0 +1,152 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +IRed='\e[0;91m' # Red +ICyan='\e[0;96m' # Cyan +Color_Off='\e[0m' # Text Reset +print_text_in_color() { + printf "%b%s%b\n" "$1" "$2" "$Color_Off" +} + +# Use local lib file in case there is no internet connection +if [ -f /var/scripts/lib.sh ] +then +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +FIRST_IFACE=1 source /var/scripts/lib.sh +unset FIRST_IFACE + # If we have internet, then use the latest variables from the lib remote file +elif print_text_in_color "$ICyan" "Testing internet connection..." && ping github.com -c 2 +then +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +FIRST_IFACE=1 . <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) +unset FIRST_IFACE +else + print_text_in_color "$IRed" "You don't seem to have a working internet connection, and /var/scripts/lib.sh is missing so you can't run this script." + print_text_in_color "$ICyan" "Please report this to https://github.com/nextcloud/vm/issues/" + exit 1 +fi + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Must be root +root_check + +# Check Ubuntu version +check_distro_version + +# Copy old interfaces files +msg_box "Copying old netplan.io config files file to: + +/tmp/netplan_io_backup/" +if [ -d /etc/netplan/ ] +then + mkdir -p /tmp/netplan_io_backup + check_command cp -vR /etc/netplan/* /tmp/netplan_io_backup/ +fi + +msg_box "Please note that if the IP address changes during an (remote) SSH connection (via Putty, or terminal for example), the connection will break and the IP will reset to DHCP or the IP you had before you started this script. + +To avoid issues with lost connectivity, please use the VM Console directly, and not SSH." +if [[ "yes" == $(ask_yes_or_no "Are you connected via SSH?") ]] +then + print_text_in_color "$IRed" "Please use the VM Console instead." + sleep 1 + exit +fi + +echo +while true +do + # Ask for IP address + cat << ENTERIP ++----------------------------------------------------------+ +| Please enter the static IP address you want to set, | +| including the subnet. Example: 192.168.1.100/24 | ++----------------------------------------------------------+ +ENTERIP + echo + read -r LANIP + echo + + if [[ $LANIP == *"/"* ]] + then + break + else + print_text_in_color "$IRed" "Did you forget the /subnet?" + fi +done + +echo +while true +do + # Ask for domain name + cat << ENTERGATEWAY ++-------------------------------------------------------+ +| Please enter the gateway address you want to set, | +| Your current gateway is: $GATEWAY | ++-------------------------------------------------------+ +ENTERGATEWAY + echo + read -r GATEWAYIP + echo + if [[ "yes" == $(ask_yes_or_no "Is this correct? $GATEWAYIP") ]] + then + break + fi +done + +# Check if IFACE is empty, if yes, try another method: +if [ -n "$IFACE" ] +then + cat <<-IPCONFIG > "$INTERFACES" +network: + version: 2 + renderer: networkd + ethernets: + $IFACE: #object name + dhcp4: no # dhcp v4 disable + dhcp6: no # dhcp v6 disable + addresses: [$LANIP] # client IP address + gateway4: $GATEWAYIP # gateway address + nameservers: + addresses: [$DNS1,$DNS2] #name servers +IPCONFIG + +msg_box "These are your settings, please make sure they are correct: + +$(cat /etc/netplan/01-netcfg.yaml)" + netplan try +else + cat <<-IPCONFIGnonvmware > "$INTERFACES" +network: + version: 2 + renderer: networkd + ethernets: + $IFACE2: #object name + dhcp4: no # dhcp v4 disable + dhcp6: no # dhcp v6 disable + addresses: [$ADDRESS/24] # client IP address + gateway4: $GATEWAY # gateway address + nameservers: + addresses: [$DNS1,$DNS2] #name servers +IPCONFIGnonvmware +msg_box "These are your settings, please make sure they are correct: + +$(cat /etc/netplan/01-netcfg.yaml)" + netplan try +fi + +if test_connection +then + sleep 1 + msg_box "Static IP sucessfully set!" +fi diff --git a/static/temporary-fix.sh b/static/temporary-fix.sh new file mode 100755 index 0000000..fec7757 --- /dev/null +++ b/static/temporary-fix.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +exit diff --git a/static/test_connection.sh b/static/test_connection.sh new file mode 100755 index 0000000..7ac65c2 --- /dev/null +++ b/static/test_connection.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +curl_to_dir() { + check_command curl -sSL "$1"/"$2" -o "$3"/"$2" +} + +# Colors +Color_Off='\e[0m' +IRed='\e[0;91m' +IGreen='\e[0;92m' +ICyan='\e[0;96m' + +print_text_in_color() { + printf "%b%s%b\n" "$1" "$2" "$Color_Off" +} + +curl_to_dir google.com google.connectiontest /tmp +if [ ! -s /tmp/google.connectiontest ] +then + print_text_in_color "$IRed" "Not connected!" +else + print_text_in_color "$IGreen" "Connected!" +fi diff --git a/static/trusted.sh b/static/trusted.sh new file mode 100755 index 0000000..2c9d95e --- /dev/null +++ b/static/trusted.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +download_static_script update-config +if [ -f $SCRIPTS/update-config.php ] +then + # Change config.php + php $SCRIPTS/update-config.php $NCPATH/config/config.php 'trusted_domains[]' localhost "${ADDRESS[@]}" "$(hostname)" "$(hostname --fqdn)" >/dev/null 2>&1 + php $SCRIPTS/update-config.php $NCPATH/config/config.php overwrite.cli.url https://"$(hostname --fqdn)"/ >/dev/null 2>&1 + + # Change .htaccess accordingly + sed -i "s|RewriteBase /nextcloud|RewriteBase /|g" $NCPATH/.htaccess + + # Cleanup + rm -f $SCRIPTS/update-config.php +fi diff --git a/static/update-config.php b/static/update-config.php new file mode 100755 index 0000000..cf88651 --- /dev/null +++ b/static/update-config.php @@ -0,0 +1,53 @@ +#!/usr/bin/php + +# Credit to: https://github.com/jnweiger + + 3) + { + # append [] to the key name, if you need to pass an array object. + if (substr($argv[2], -2) === '[]') + { + $CONFIG[substr($argv[2],0,-2)] = array_slice($argv,3); + } + else + { + $CONFIG[$argv[2]] = $argv[3]; + } + } +else + { + # exactly two parameter given -- means delete. + unset($CONFIG[$argv[2]]); + } + +$text = var_export($CONFIG, true); +## A warning is printed, if argv[1] is not writable. +## PHP does not issue proper errno or strerror() does it? +file_put_contents($argv[1], " diff --git a/static/update.sh b/static/update.sh new file mode 100755 index 0000000..ed35eb9 --- /dev/null +++ b/static/update.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# T&M Hansson IT AB © - 2019, https://www.hanssonit.se/ + +# shellcheck disable=2034,2059 +true +# shellcheck source=lib.sh +. <(curl -sL https://raw.githubusercontent.com/nextcloud/vm/master/lib.sh) + +# Check for errors + debug code and abort if something isn't right +# 1 = ON +# 0 = OFF +DEBUG=0 +debug_mode + +# Must be root +root_check + +mkdir -p "$SCRIPTS" + +if [ "${1}" = "minor" ] +then + echo "$((NCMAJOR-1))" > /tmp/minor.version +fi + +# Delete, download, run +run_main_script nextcloud_update + +exit