Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Wednesday, April 12, 2017

Lessons learned Docker microservices architecture with Spring Boot

Introduction

During my last project consisting of a Docker microservices architecture, built with Spring Boot, using RabbitMQ as communication channel, I learned a bunch of lessons, here's a summary of them.

Architecture

Below is a high level overview of the architecture that was used.


Docker

  • Run 1 process/service/application per docker container (or put stuff in init.d but that's not intended use of docker)

  • Starting background processes in the CMD cause container to exit. So either have a script waiting at the end (e.g tail -f /dev/null) or keep the process (i.e the one prefixed with CMD) running in the foreground. Other useful Dockerfile tips you can find here

  • As far as I can tell Docker checks if Dockerfile has changed, and if so, creates a new image instance (diffs only?)

  • Basic example to start RabbitMq docker image, as used in the build tool:

    $ docker pull 172.18.19.20/project/rabbitmq:latest
    docker rm -f build-server-rabbitmq
    $ # Map the RabbitMQ regular and console ports
    $ docker run -d -p 5672:5672 -p 15672:15672 --name build-server-rabbitmq 172.18.19.20/rabbitmq:latest

  • If there's no docker0 interface (check by running command ifconfig) then probably there are ^M characters in the config file at /etc/default/docker/docker.config. To fix it, perform a dos2unix on that file.

  • Check for errors at startup of docker in /var/log/upstart/docker.log

  • If your docker push <image> asks for a login (and you don't expect that) or it returns some weird html like "</html>" then you're probably missing the host in front of the image name, e.g: 172.18.19.20:6000/projectname/some-service:latest

  • Stuff like /var/log/messages is not visible in a Docker container, but is in its host! So look there for example to find out why a process is not starting/gets killed at startup without any useful logging (like we had with clamd)

  • How to remove old dangling unused docker images: docker rmi $(docker images --filter "dangling=true" -q --no-trunc)

Spring Boot

  • Some jackson2 dependencies were missing from the generated Spring Initializr project, noticed when creating unittests. These dependencies were additionally needed in scope test:

    <dependency>
      <groupid>com.fasterxml.jackson.core</groupid>
      <artifactid>jackson-databind</artifactid>
      <version>2.5.0</version></dependency>
    <dependency>
      <groupid>com.fasterxml.jackson.core</groupid>
      <artifactid>jackson-annotations</artifactid>
      <version>2.5.0</version></dependency>
    <dependency>
      <groupid>com.fasterxml.jackson.core</groupid>
      <artifactid>jackson-core</artifactid>
      <version>2.5.0</version></dependency>


    Not sure anymore why these then didn't get <scope>test</scope> then... Guess it was needed also in some regular code... :)

  • In the Spring Boot AMQP Quick Start the last param has name .with(queueName) during binding, but that's the topic key! (which is related to the binding key used at sending), so not the queue name.

  • Spring Boot Actuator's /health will check all related dependencies! So if you have a dependency in your pom.xml to a project which uses spring-boot-starter-amqp, /health will check now for an AMQP queue being up! So add a for those if you don't want that.

  • Spring Boot's default AppAplicationIT probably needs a @DirtiesContext for your tests, otherwise the tests might re-use or create more beans than you think (we saw that in our message receiver tests helper class).

  • @Transactional in Spring: by default only for unchecked exceptions!! It's documented but still a thing to watch out for.

  • And of course: Spring's @Transactional does not work on private methods (due to proxy stuff it creates)

  • To see in Spring Boot the transaction logging, put this in application.properties:

    logging.level.org.springframework.jdbc=TRACE
    logging.level.org.springframework.transaction=TRACE


    Note that by default @Transactional just rolls back, it does not log anything, so if you don't log your runtime exceptions, you won't see much in your logs.

  • mockMvc from spring is not really invoking from "outside", our spring sec context filter (for which you can use @Secured(role)) was allowing calls while no authentication was provided for. RestTemplate seems to work from "the outside".

  • Scan order can mess up @ControllerAdvice error handler it seems. Had to change the order sometimes:

    Setup:
    - Controller is in: com.company.request.web.
    - General error controller is in com.company.common package.

    Had to change
    @ComponentScan(value = {"com.company.security", "com.company.common", "com.company.cassandra", "com.company.module", "com.company.request"})

    to

    @ComponentScan(value = {"com.company.security", "com.company.cassandra", "com.company.module", "com.company.request", "com.company.common"})

    Note that the general error controller has now been put in last

  • Spring Boot footprint seems relatively big especially for microservices. At least 500MB or something is needed, so we have quite big machines for about 20 services. Maybe plain Spring (iso Spring boot) might be more lightweight...

Bamboo build server

  • When Bamboo gets slow and the CPU seems quite busy and memory availability on its server seems fine, increase the Xmss and Xmsx (or related). Found this out because the java Bamboo process was running out of heap sometimes, increasing heap also fixed performance.

  • To have Bamboo builds fail on quality gates not met in SonarQube, install in Sonar the build breaker plugin. See the plugin docs and Update Center. This FAQ says so.

Stash

  • The Stash (now called Bitbucket) API: in /rest/git/1.0/projects/{projectKey}/repos/{repositorySlug}/tags a 'slug' is just a repository name. 

Microservices with event based architecture

  • When you do microservices, IMMEDIATELY take into account during coding + reviews that multiple instances can do concurrent access to database.

    This has affect on your queries. Most likely correct implementation for uniqueness check on inserts:
    1- add unique constraint
    2- run insert
    3- catch uniqueness exception --> you know it already exists. Solution with SELECT NOT EXISTS is not guaranteed unique.

  • Also take deleting of data (e.g user deletes himself) into account from the start. Especially when using events and/or eventual consistency in combination with an account-balance or similar. Because what if one services in the whole chain of things to execute for a delete fails? Has the user still some money left on his/her account then? In short: take care of CRUD.

  • Multiple services are sending the same event? That can indicate 2 services are doing the same thing --> Not good probably.

  • Microservices advantages:

    - Forces you to better think about where to put stuff in comparison to monolith where you more often can be tempted to "just do a quick fix".
    - language independency for service implementation: choose the best language for the job

    Disadvantages:
    - more time needed for design
    - eventual consistency is quite tough to understand & work with, also conceptually
    - infrastructure is more complex including all communication between services

    More cons can be found here.

Tomcat

  • Limit the maximum size of what can be posted to a servlet is not as easy as it seems for REST services:

    - maxPostSize in Tomcat is enforced only for specific contenttype: Tomcat only enforces that limit if the content type is application/x-www-form-urlencoded

    - And the other 3 below XML options are for multipart only:

    <multipart-config>
      <!-- 52MB max -->
      <max-file-size>52428800</max-file-size>
      <max-request-size>52428800</max-request-size>
      <file-size-threshold>0</file-size-threshold></multipart-config>


    So that one won't work for uploading just a byte[]. The only solution is in the servlet (e.g Spring @Controller) you'll have to check for the limit you want to allow.

  • maxthreads seems set to be unlimited by default or something. 50 seems to perform better. (workerthreads) 

Security

  • To securely generate a random number: SecureRandom randomGenerator = SecureRandom.getInstance("NativePRNG");

  • Good explanation of secure use of a salt to use for hashing can be found here

Cassandra

  • Unique constraints are not possible in Cassandra, so there you will even have to implement unique constraints in the business logic (and make it eventually consistent)

  • CassandraOperations query for one field:

    Select select = QueryBuilder.select(MultiplePaymentRequestRequesterEntityKey.ID).from(MultiplePaymentRequestRequesterEntity.TABLE_NAME);
    select.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);
    select.where(QueryBuilder.eq(MultiplePaymentRequestRequesterEntityKey.REQUESTER, requester));
    return cassandraTemplate.queryForList(select, UUID.class);


    See also here.

  • Note below two keys don't seem to get picked up by Cassandra in the Spring Data Cassandra version 1.1.4.RELEASE:  

    <groupid>org.springframework.data</groupid>
    <artifactid>spring-data-cassandra</artifactid>

    @PrimaryKeyColumn(name = OTHER_USER_ID, ordinal = 0, type = PrimaryKeyType.PARTITIONED)
    @CassandraType(type = DataType.Name.UUID)
    private UUID meUserId;

    @PrimaryKeyColumn(name = ME_USER_ID, ordinal = 1, type = PrimaryKeyType.CLUSTERED)
    @CassandraType(type = DataType.Name.UUID)
    private UUID meId;

    This *does* get picked up: put it into a separate class:

    @Data
    @AllArgsConstructor
    @PrimaryKeyClass
    public class HistoryKey implements Serializable {

      @PrimaryKeyColumn(name = HistoryEntity.ME_USER_ID, ordinal = 0, type = PrimaryKeyType.PARTITIONED)
      @CassandraType(type = DataType.Name.UUID)
      private UUID meUserId;

      @PrimaryKeyColumn(name = HistoryEntity.OTHER_USER_ID, ordinal = 1, type = PrimaryKeyType.PARTITIONED)
      @CassandraType(type = DataType.Name.UUID)
      private UUID otherUserId;

      @PrimaryKeyColumn(name = HistoryEntity.CREATED, ordinal = 2, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING)
      private Date created;

    }

  • Don't use Cassandra for all types of use cases. An RDMS still has its value, e.g for ACID requirements. Cassandra is eventually consistent.

Kubernetes

Miscellaneous

  • Use dig for DNS resolving problems

  • Use pgAdmin III for PostgreSQL GUI

  • To stop SonarQube complaining about unused private fields when using Lombok @Data annotation: add to each of those classes @SuppressWarnings("PMD.UnusedPrivateField")

  • Managed to not need transactions nor XA transactions for message publishing, message reading, store db, message sending, by using the confirm + ack mechanism.
    And allow message to be read again. DB then sees: oh already stored (or do an upsert).
    So,when processing message from the queue:
    1- store in db
    2- send message on queue
    3- only then ack back to queue that read was successful

  • Performance: instantiate the Jackson2 ObjectMapper once as static, not in each call, so:
    private static final ObjectMapper mapper = new ObjectMapper();
  • Javascript: when an exception occurs in a callback and it is not handled, processing just ends. Promises have better error handling.

  • clamd would not start correctly; it would try to start but then show 'Killed' when started via the commandline. Turns out it runs out of memory when starting up.  Though we had enough RAM (16G total, 3G free), it turns out clamd needs swap configured!

  • Linux bash shell script to loop through projects for tagging with projects with spaces in their name:

    PROJECTS="
      project1
      project space2
    ";
    IFS=$'\n'
    for PROJECT in $PROJECTS
    do
      TRIM_LEADING_SPACE_PROJECT="$(echo -e "${PROJECT}" | sed -e 's/^[[:space:]]*//')"
      echo "Cloning '$TRIM_LEADING_SPACE_PROJECT'"
      git clone --depth=1 http://$USER:$GITPASSWD@github.com/projects/$TRIM_LEADING_SPACE_PROJECT.git
    done

  • OpenVPN in Windows 10: Sometimes it hangs on "Connecting..."  It doesn't show the popup to enter username/pwd. Go to View logs. Then when you see: Enter management password in the logs: ???? you have to kill the OpenVPN Daemon under Processes tab (windows taskmanager). The service is stopped when exiting the app but that's not enough!

  • javascript/nodejs log every call that comes in:

    app.use(function (req, res, next) {
      console.log('Incoming request = ' + new Date(), req.method, req.url);
      logger.debug('log at debug level');
      next()
    }

  • If ever your mouse is suddenly not working anymore your VirtualBox guest, kill the process in your guest-machine mentioned in comment 5 here. After that the mouse works again in your vbox guest.

  • Fix Firefox to version 45.0.0 for selenium driver tests:

    sudo apt-get install -y firefox=45.0.2+build1-0ubuntu1
    sudo apt-mark hold firefox

  • Setting the cookie attribute Secure (indicating cookie should only be sent over httpS) can be seen when using curl to request the URL(s) that should send that cookie plus the new attribute, even when using HTTP. See also my previous post.

    But when using a browser and HTTP, you probably won't see the secure cookie appear in the cookie store. This is (probably) because the browser knows not to store it in that case because it's HTTP being used.

  • Idempotency within services is key for resilience and be able to resend an event or perform an API call again.

Sunday, July 18, 2010

Best of this Week Summary 28 June - 18 July 2010

Sunday, May 23, 2010

Best of this Week Summary 17 May - 23 May 2010

  • Codelab ("tutorial") from Google that "shows how web application vulnerabilities can be exploited and how to defend against these attacks. The best way to learn things is by doing, so you'll get a chance to do some real penetration testing, actually exploiting a real application. The codelab is built around Jarlsberg, a small, cheesy web application that allows its users to publish snippets of text and store assorted files. "Unfortunately," Jarlsberg has multiple security bugs ranging from cross-site scripting and cross-site request forgery, to information disclosure, denial of service, and remote code execution. The goal of this codelab is to guide you through discovering some of these bugs and learning ways to fix them both in Jarlsberg and in general."

  • A new IBM Redbook on WebSphere Messaging and High Availability has just been released.

  • A cool Android with Hudson continuous integration. Led on mobile phone changes color depending on the build status. Remember the Lava Lamps version?

  • Java dynamic proxies explained. They are for example used in Hibernate for lazy loading entities and in Spring for AOP. Also explains what CGLib proxies are for.

Sunday, May 16, 2010

Best of this Week Summary 10 May - 16 May 2010

Sunday, April 18, 2010

Best of this Week Summary 12 April - 18 April 2010

Sunday, April 11, 2010

Best of this Week Summary 5 April - 11 April 2010

Sunday, February 28, 2010

Best of this Week Summary 22 February - 28 February 2010

Sunday, February 21, 2010

Best of this Week Summary 15 February - 21 February 2010

  • Expected that Mozilla uses Agile everywhere, and definitely on its flagship Firefox? Think again, only recently they started to combine Agile and more traditional Waterfall as their new development model, dubbed "Lorentz".

  • Tips for hardening your Tomcat installation. Other implementation guides, not only limited to Tomcat (also for example WebLogic) tips from U.S. DOD DISA (Defense Information Systems Agency) can be found here.

  • Always interesting to at least quickly browse through: a review of the 1993 code of Doom. And more "today": the code of Doom for the iPhone reviewed.

  • Think you know Javascript? Try one of these quizes!

Sunday, October 25, 2009

Best of this Week Summary 19 October - 25 October 2009

Sunday, August 23, 2009

Best of this Week Summary 17 August - 23 August 2009

  • Here's a basic list of software architecture review guidelines. You can definitely also use it as a starting point for your documentation, or to see if your documentation is covering it all.

  • Shame on me: forgot to mention last week the VMWare acquisition of SpringSource! Basically the CTO says "the aim of this acquisition is to provide a comprehensive platform as a service (PaaS)". Here's a view on it from a technical level by Adrian Colver (SpringSource), and here's one from Frank Cohen.

  • Potential cloud "dangers" described during Black Hat USA 2009.

  • And related to the previous one, here's a short summary with interesting results on stress testing the Amazon EC2, Google AppLogic and Microsoft Azure cloud solutions. Bascically, the performance quite varied and response times varied by a factor of 20! And good to know: on Google AppEngine, any task can not last longer than 30 seconds!

  • Need to know "everything" about Java Generics? Then this large PDF Java Generics FAQs - Frequently Asked Questions is for you. Think you know everything about Generics? It still might be for you. For example, do you know what this says: "Enum<E extends Enum<E>>"? Or can you follow this one: "Can I use the type parameter of an outer type as part of the bounds of the type parameter of an inner type or a method?"? :)

Sunday, August 9, 2009

Best of this Week Summary 3 August - 9 August 2009

Sunday, April 12, 2009

Best of this Week Summary 06 April - 12 April 2009

Saturday, February 21, 2009

Best of this Week Summary 16 February - 22 February 2009

Sunday, January 18, 2009

Best of this Week Summary 12 January - 19 January 2009

Saturday, October 11, 2008

Best of this Week Summary 06 October - 12 October 2008

  • One of the many nice editions of The A-Z of Programming Languages series, this time on C#. Yes, yes, that word is not supposed to be on this blog, but this article is still interesting if you're into programming languages. For example the challenges when designing a language. Check also the other editions, for example about: AWK, Forth, Modula-3, Python and Javascript.

  • An Amazon S3 introduction/beginners guide for setting up hosting of images.

  • Four cases of CSRF attacks desribed, including one were it was possible to transfer money from a bank account! Check also the mentioned paper on how to prevent them: Cross-Site Request Forgeries: Exploitation and Prevention. The paper explains how to prevent CSRF in your web-application/frameworks: don't let a GET modify anything and pass a random number in the cookie and each form POST. It also describes XSS and the same-origine policy.

Saturday, September 27, 2008

Best of this Week Summary 22 September - 28 September 2008

Monday, August 11, 2008

Best of this Week Summary 04 August - 10 August 2008

  • Good article on the current status of Ajax frameworks. Most interesting is the notion that in 2005 there were already 48 Ajax frameworks and in 2007 there were already 240! Clearly the expected consolidation did not occur yet. Nice conclusion I agree with at the end: for Ajax use Prototype and script.aculo.us, they have been around for 3-4 years. For more heavyweight RIA applications use Flex (Silverlight is in a too early stage). What about AIR? I'd say the same. Though AIR needs its own runtime, so is a bit different.

  • Good intro on google's recently introduced open sourced binary encoding format Protocol Buffers, including references to pros and cons articles.

  • Recently the Open Web Foundation was launched. It "[...] will be focused on developing the technical specifications of protocols used for communication and inter-operability between applications on the web. The foundation will also set out the legal terms and best practices for the use and transport of both private and public data, and the usage of web services". Here's how it relates to the Data Portability Working Group and who's in it.

  • Microsoft is now sponsoring the Apache Software Foundation. Note that is not a move away from IIS, as mentioned in the referred blog in the article.

  • Drizzle is the name of the new lightweight MySQL spin-off, which aims at systems that have to process massive amounts of concurrency (mostly reads) on multicore systems. Think Cloud and Net(?) applications. Or, as they say it: "A High-Performance Microkernel DBMS for Scale-Out Applications ".

  • Quite elaborate article and comparison on how secure the current major web frameworks are.
    Discussed are: Struts, Spring MVC 2, Struts2, Spring, Webwork, Stripes, JSF, MyFaces, Wicket and MS .Net.

Saturday, July 26, 2008

Best of this Week Summary 15 July - 27 July 2008

Sunday, March 9, 2008

Best of this Week Summary 03 March - 09 March 2008

  • Good article on Premature Code Optimization and the often made (invalid) conclusion: 'as a developer I don't need to optimize until the code is finished'.

  • Practical use of Java in four web conferencing products described. Including integration with Flash.

  • A talk with the director of engineering at Google about OpenSocial. Most interesting point is that indeed OpenSocial is not to interconnect social networks. Unless they are Social Graph enabled, but there is no site that supports it yet. Google also released the Contacts API this week.

  • Related to that is Higgins: "An open identity framework designed to integrate identity, profile and social relationship information across multiple sites, applications and devices. Supports multiple identities because you don't want to use the same identity for MySpace as for your financial sites." Contributors include the big names like Google, IBM and Oracle.

Sunday, January 27, 2008

Best of this Week Summary 21 January - 27 January 2008

  • Nice routing pattern for webservices that need to provide both synchronous and a-synchronous calls. You can even make the router such that depending on certain criteria (like load, response time), it will either turn the call into an a-synchronous call when needed. Disadavantage of this approach is of course that the caller has to be able to support both an a-synchronous and a synchronous version of each call. Related patterns you can find in these seven Self-Service: select application patterns.

  • An effort to give answer to the question whether Tomcat is an application server or not. GREAT introduction to JEE btw, so good read for beginners or as a refresher. The answer: Tomcat does not support the entire Java EE stack: no distributed transactions, EJBs, and JMS.

  • IBM made their Jazz tool available for the public. It can be used to "build a scalable, extensible team collaboration platform for integrating work across the phases of the development lifecycle." Note that it is not fully opensource yet. There's also a Mylyn connector available for Jazz.

  • Version 3.0.0 of HTML Purifier has been released. It will scan your HTML for malicious XSS code, check for compliance and will try to fix your code.

  • Summary of a statement made by Bruce Eckel in this article that Java should not change much anymore: it should stop growing and just become stable, and Sun should focus on optimizing/extending the JVM. Interesting considerations.

  • And finally for this week, for the developers among us, a bunch of shortcut keys in Eclipse you might not know about.

  • The Open Source hardening Project of the US Homeland Security department together with Coverity has led to the milestone where in 11 opensource projects all main bugs have been fixed. These 11 have been moved up to the new level Rung 2. Here you can see all the results of the scan.